Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Нужно избавиться от подзапросов. Выборка sql  [new]
Sofie
Member

Откуда:
Сообщений: 9
Здравствуйте. Очень нужна помощь по оптимизации запроса.
Задание: Добавить новый заголовок документа (одной командой insert);
-Номер документа = последний номер документа+1;
-Дата=текущая дата;
-Тип=расход,если документов типа "приход "больше ,чем документов типа "расход".В противном случае тип=приход.
-Учесть,что в таблице DMZ изначально может не быть ни одной строки.

Таблица DMZ - документ.DDM - дата, NDM- номер документа,PR - приход/расход (1-приход, 2-расход)товара.
Сам запрос есть :
INSERT INTO DMZ (DDM, NDM, PR)
SELECT
GETDATE() DDM,
(isnull((SELECT MAX(NDM) FROM DMZ), 0) + 1) NDM,
CASE WHEN
isnull((SELECT COUNT(*) FROM DMZ WHERE PR = 1), 0) >
isnull((SELECT COUNT(*) FROM DMZ WHERE PR = 2), 0)
THEN 2
ELSE 1
END

Запрос работает , но нужно его оптимизировать,заменив два запроса в операторе CASE на один.Как это сделать?

Прилагаю диаграмму бд,если это поможет для понимания.

К сообщению приложен файл. Размер - 13Kb
18 апр 17, 17:01    [20411686]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
Serп
Guest
Я так думаю, что если все документы в таблицу добавляются вашим способом, то для определения типа очередного достаточно посмотреть тип предыдущего...
18 апр 17, 17:15    [20411745]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
Sofie
Member

Откуда:
Сообщений: 9
Serп,
Да, но сначала надо узнать ,какой будет предыдущий
18 апр 17, 17:17    [20411753]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
Sofie
Member

Откуда:
Сообщений: 9
В общем, не знаю, точно ли , но решение примерно такое :
INSERT INTO DMZ (DDM,NDM,PR)
SELECT
GETDATE() DDM, (isnull((SELECT MAX(NDM) FROM DMZ),0)+1) NDM,
CASE
WHEN ISNULL(SUM(CASE PR WHEN 1 THEN 1 ELSE 0 END), 0) > ISNULL(SUM(CASE PR WHEN 2 THEN 1 ELSE 0 END), 0)
THEN 2
ELSE 1
END
FROM DMZ

Может , кто-нибудь найдет ошибку...
18 апр 17, 17:37    [20411837]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31993
Sofie
Запрос работает , но нужно его оптимизировать,заменив два запроса в операторе CASE на один.Как это сделать?
Ну, можно заменить одним запросом.
CASE WHEN
isnull((SELECT COUNT(*) FROM DMZ WHERE PR = 1), 0) > 
isnull((SELECT COUNT(*) FROM DMZ WHERE PR = 2), 0)
THEN 2
ELSE 1
END
на
ISNULL((SELECT CASE WHEN SUM(CASE PR WHEN 1 THEN 1 ELSE 0 END) > SUM(CASE PR WHEN 2 THEN 1 ELSE 0 END) THEN 2 ELSE 1 END FROM DMZ), 1)


Но ещё лучше взять последний, если известна очерёдность (например, по инкрементному ID записи), если это допустимо по бизнес-логике приложения.
Если поле NDM является ПК, то будет очень быстро.
CASE WHEN ISNULL((SELECT TOP 1 PR FROM DMZ ORDER BY NDM DESC), 2) = 1 THEN 2 ELSE 1 END
18 апр 17, 17:40    [20411845]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31993
Sofie
-Тип=расход,если документов типа "приход "больше ,чем документов типа "расход". В противном случае тип=приход.
А вообще конечно бизнес-логика аховая :-)
18 апр 17, 17:42    [20411857]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
Sofie
Member

Откуда:
Сообщений: 9
alexeyvg,

Да,это поле ПК.
Можете немного объяснить последний запрос?
18 апр 17, 17:43    [20411862]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3757
alexeyvg
Sofie
-Тип=расход,если документов типа "приход "больше ,чем документов типа "расход". В противном случае тип=приход.
А вообще конечно бизнес-логика аховая :-)

даааааа
18 апр 17, 17:50    [20411885]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31993
Sofie
alexeyvg,

Да,это поле ПК.
Можете немного объяснить последний запрос?

Запросом TOP 1 ... ORDER BY DESC мы получаем последнюю запись в указанной сортировке, т.е. запись с максимальным значением поля, указанного в сортировке.

Т.е. запрос:
SELECT TOP 1 PR FROM DMZ ORDER BY NDM DESC

возвращает поле PR у записи, которая была вставлена последней, т.е. у которой поле NDM имеет максимальное значение.
18 апр 17, 18:15    [20411938]     Ответить | Цитировать Сообщить модератору
 Re: Нужно избавиться от подзапросов. Выборка sql  [new]
Sofie
Member

Откуда:
Сообщений: 9
alexeyvg,

Понятно.Спасибо вам большое!
18 апр 17, 18:21    [20411962]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить