|
v7: Самые поздние даты закупок SQL | ☑ | ||
---|---|---|---|---|
0
Владимир1С
04.03.19
✎
11:00
|
Есть таблица, с записями о закупках. Кто, когда. Необходимо одним запросом , можно пакетным, получить даты самых последних закупок.
Есть работающий запрос: SELECT Клиенты.CODE Код , MAX(Дисконт.DATE_TIME_IDDOC) ДатаДокумента FROM $Регистр.Дисконт AS Дисконт With (NOLOCK) INNER JOIN $Справочник.Клиенты AS Клиенты With (NOLOCK) ON $Дисконт.Клиент = Клиенты.ID GROUP BY Клиенты.CODE ORDER BY Клиенты.COD Но, методически,кажется, он неверен: нужно брать первое значение Дисконт.DATE , при сортировке по убыванию или последнее при сортировке по возрастанию. Хотя, сортировка, это опять операция сравнения, как и в функции MAX. Вопрос: Есть ли возможность исключить сравнения дат, ограничившись только одной выборкой, при которой запрос будет выдавать наружу только последнее выбранное значение, при чём, по каждому отдельному клиенту? |
|||
1
viktor_vv
04.03.19
✎
11:08
|
Без сортировки никак . Можешь так попробовать , тут без group by может побыстрее быть
SELECT Клиенты.CODE Код , (Select top 1 Дисконт.DATE_TIME_IDDOC From $Регистр.Дисконт AS Дисконт With (NOLOCK) Where $Дисконт.Клиент = Клиенты.ID Order by Дисконт.DATE_TIME_IDDOC DESC) as DateLast FROM $Справочник.Клиенты AS Клиенты With (NOLOCK) //FROM $Регистр.Дисконт AS Дисконт With (NOLOCK) ORDER BY Клиенты.COD |
|||
2
viktor_vv
04.03.19
✎
11:10
|
И в таблице $Регистр.Дисконт очень желателен составной индекс по полям (Клиент , DATE_TIME_IDDOC )
|
|||
3
Ёпрст
04.03.19
✎
11:10
|
(0) ну и бери или max или min в тексте запроса.
|
|||
4
Владимир1С
04.03.19
✎
11:21
|
(1)спасибо. Очень жаль, надеялся на возможность ликвидации операции сравнения. Что MAX, что просто сортировка, один предмет с разных видов.
(2) В то то и дело, хорош этот индекс, когда с самого начала, а так, достраивать его на лету, бессмысленно, с точки зрения времязатрат. |
|||
5
viktor_vv
04.03.19
✎
11:29
|
(4) А без сортировки сравнения для этой задачи никак . Так индекс-то там несложно , там как раз на поле Клиент поставить галку отбор движений , как раз и получится составной (Клиент , DATE_TIME_IDDOC) , если правильно помню.
|
|||
6
Sserj
04.03.19
✎
11:38
|
(0) Смотря какой у тебя SQLServer, если 2005 и выше, то там есть оконные функции, хотя не помню точно в каком развитии, потому что они изначально были не полностью реализованы были. Но в 2008 к примеру можно так:
SELECT Клиенты.CODE, Продажи.ДатаДок FROM (SELECT $Дисконт.Клиент as Клиент , Дисконт.DATE_TIME_IDDOC as ДатаДок , ROW_NUMBER() OVER (PARTITION BY $Дисконт.Клиент ORDER BY Дисконт.DATE_TIME_IDDOC DESC) as номерПродажи FROM $Регистр.Дисконт AS Дисконт With (NOLOCK) ) AS Продажи INNER JOIN $Справочник.Клиенты AS Клиенты With (NOLOCK) ON Продажи.Клиент = Клиенты.ID WHERE Продажи.номерПродажи = 1 Преимущество в том что оконные функции работают в многопоточном режиме. |
|||
7
Владимир1С
04.03.19
✎
11:46
|
(6) Большое спасибо, многопоточность буду иметь ввиду, когда перейду с 2005 SQL на другой.
|
|||
8
Salimbek
04.03.19
✎
13:37
|
(0) Да все у тебя правильно, и при нормальных индексах - должно быстро работать.
|
|||
9
Salimbek
04.03.19
✎
13:40
|
Если конкретнее, то "исключить сравнения дат" - СКЛ и так не сравнивает даты. Когда задаешь Макс - он тупо берет наибольшее значение из индекса.
Но если же хочешь именно "исключить сравнения дат" - то значит надо создавать отдельный справочник и туда писать дату последней закупки. И учесть, что при отмене проведения какого-либо Документа - надо посмотреть, а вдруг это и есть Дата последней закупки, и если так, то находить предыдущий Док и записывать его дату. Как по мне - то через чур сложно и не стоит оно того. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |