![]() |
украшаем запрос MS SQL
1. можно ли как-то запустить Query Analyzer (2000) с ярлычка, чтоб он не заново запускался, а создал окошко в уже открытом аналайзере? А то задолбал плодиться, я забываю смотреть, есть он в живых или нет.
2. есть уже заполненная табличка: Код:
declare @dates1 table ( |
для MS SQL есть свой раздел форума
2. сразу сделать правильную (необходимую) выборку. Временные таблицы - очень ресурсоёмкое решение, так ли они нужны в данном случае? |
Цитата:
Может я неправильно понимаю как оно работает, обрисую задачу: Есть табличка с оплаченными повременными услугами, примерно миллион-два записей (с 2004 года). Из них нужно выбрать такие записи за последние 4 недели, которые бы оплачивали одну и ту же услугу в одно и то же время, то есть выяснить какие есть перекрытия оплат. Табличка имеет много всяких полей, я выбрал только нужные 4 поля за последние недели (около 1000 строчек), а потом искал пересечения Код:
delete from |
pva
1. Запускать скриптом, который проверяет наличие QA и либо запускает, либо активирует окно и отправляет комбинацию <Ctrl+N> |
pva, я бы всё-таки работал с изначальной таблицей
где-то примерно так: Код:
select groupId, дата, count (*) (в примере не понял соотношение dateIn и dateOut) |
дело в том, что граница оказания услуг может быть и не кратна дню, пример:
услуга 1: от '2008-01-01 12:00:00' до '2008-01-02 14:00:00' услуга 2: от '2008-01-01 18:00:00' до '2008-01-02 12:00:00' |
т.е. имеем ряд временных диапазонов, нужно выбрать накладывающиеся? - да, группировкой тут не обойтись :-(
хотя всё равно не такой уж и монстрообразный запрос получается: Код:
select u1.* |
Busla, Я приведу пример когда этот вариант не работает:
Код:
and (u1.dateIn beetwen u2.dateIn and u2.dateOut or u1.dateOut beetwen u2.dateIn and u2.dateOut) Код:
u1 11111111111111 Код:
select |
pva, всё правильно. Ты просто забываешь, что помимо
Код:
.....время................ |
не-а, не забываю :-P если список состоит только из этих двух записей, то твой вариант запроса выдаст только одну. А надо обе (это всё необходимо для отчёта, чтобы потом человек посмотел пересечения и принял решение, что из них поправить)
|
остаётся вопрос с временными view. Можно такие сделать? На сколько это критично к ресурсам? у меня услуги - это
Код:
accDebet join accCliPay on (accCliPay.accPayId=accDebet.accPayId and accCliPay.payCod=1) |
Да, запрос у меня получился несколько однобокий.
AFAIK вьюхи интерпритируются примерно как макрос - т.е. хранится только код запроса, и он подставляется в другие запросы - содержимое view никак специально не индексируется, не кешируется и т.п. Можно использовать не view, а подзапрос: Код:
select * |
когда идентичные - это нормально, нужно обе выдавать. Вот теперь красиво получилось! Пасиба *DRINK*. Единственное, со знаком ">=" всё-таки надо строгое ограничение (без =), потому что если одна услуга заканчивается '2008-09-18 12:00' а другая начинается в это же время - это не пересечение
|
Цитата:
View, с точки зрения программиста - SQL-запрос/макрос хранимый на стороне сервера. С точки зрения видимости - таблица БД. Т. е. этакая виртуальная динамическая таблица. Т. к. View практически ничего не занимают, то смысла Создавать-Удалять их в процессе выполнения нет никакого. Более того, с точки зрения структурирования и изоляции кода это глупость. Хочу заметить, что связка нескольких View в одном запросе читабельнее чем один сложный запрос с join. Если вы хотите использовать конструкции управляемые в процессе выполнения, обратите внимание на хранимые процедуры. |
Цитата:
Цитата:
|
Цитата:
Цитата:
Тоже не плохой выход, особенно с точки зрения, работы с высоконагруженными базами. Наверно, самый оптимальный случай особенно при очень сложных выборках. С точки зрения блокировок, "монолитный" запрос это самое печальное. |
Цитата:
Цитата:
|
Цитата:
Естественно придется жертвовать памятью ради скорости, либо наоборот. Что касаемо индексов. Вроде бы человек туда уже агрегированные данные собирается выгружать? Если же нет, то вы правы, когда размер временной таблицы соизмерим с основной, то смысла это не имеет. Однако, повторюсь: 1) Лично я бы работал с View. 2) С MS SQL не работал давно, за сим мои мысли о проиводительности можно опустить, как ламерские :) |
Цитата:
Цитата:
|
pva,
Может быть имеет смысл применить функции пользователя ? Будете передавать в нее две переменных (временной диапазон), получать таблицу. |
Не совсем то. 2 вызова одно функции приведёт к вычислению 2 раз одного и того же запроса, а мне хочется на этом съэкономить и не засорять базу
|
pva, это уже - маленький простой запрос - его можно слегка переформулировать, разбить на части, усложнить. Но MS SQL это не тупой интерпретатор наподобие MySQL - простой запрос он сам выполнит оптимальным образом основываясь на текущей ситуации. Промежуточные таблицы, подпрограммы и т.п. только ухудшат его работу и читаемость.
|
Занялся народным творчеством дабы улучшить жизнь любимым девушкам в любимой конторе. Родил кучу вопросов. Продолжаем:
1. Есть ли стандартная функция в SQL, которая выбираем минимум или максимум из 2-х значений 2. Можно ли как-то сделать временную функцию (для экономии кода) вида: Код:
-- ограничить и превратить во float Код:
CREATE function dbo.fmin(@a float, @b float) returns float |
а зачем datetime во float переводить? - это немножко хак, без которого вполне можно обойтись.
select предназначен немножко для другого, просто присвоить переменной значение можно через set: Код:
set @a = convert(float, @date_a), @b = convert(float, @date_b) |
Продолжаем тему про временный view. У меня одна процедурка время от времени блокировала работу всегод отдела. Нужно выбрать последнее по дате значение какого-то параметра из сложного запроса, сделано типа так:
Код:
select top 1 /*запрос*/ Код:
select top 1 /*запрос*/ 2. есть ли альтернативные способы выбрать из таблицы элемент с максимальным значением, без такой блокировки других пользователей |
Цитата:
Задача: Вывести строку в которой d.date максимальна (последнее по дате) Решение: Вывести ВСЮ таблицу (естественно создается какая-то внутренняя системная буферная переменная), отсортировать (в данном буфере), и взять первое значение. А если в таблице миллионы строк? Не индус писал? Кстати поле d.date - индексированно? ==== Цитата:
|
Временной таблицы не было, стоял большой where, который я переделал в join и переименовал однобуквенные переменные в многобуквенные. Дата проиндексирована (по возрастанию)
Код:
select top 1 |
Время: 14:35. |
Время: 14:35.
© OSzone.net 2001-