Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Евгенич Member Откуда: Сообщений: 269 |
Добрый день! Прошу помощи Имеется таблица MS SQLSERVER 2012: create table #table1(id int identity,repdate datetime, date1 datetime,date2 datetime,date3 datetime,date4 datetime) insert #table1 select '20180501','20171226','20180326','20180626','20180926' union all select '20180501','20170823','20171123','20180223','20180523' Необходимо найти для каждой строки минимальную из дат date1,date2,date3,date4 большую чем repdate. То есть для первой строки это будет значение '20180626', для второй '20180523' Заранее благодарю за помощь! |
12 янв 18, 10:03 [21100007] Ответить | Цитировать Сообщить модератору |
Добрый Э - Эх
Guest |
Евгенич, не хватает в скульсервере таких вещей, как greatest и least... :) а так - развернуть строку в столбец (UNPIVOT), взять минимум (MIN). при необходимости - снова развернуть в строку (PIVOT) |
12 янв 18, 10:09 [21100035] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6801 |
Евгенич,SELECT * FROM #Table1 a CROSS APPLY ( SELECT [MaxDate] = MAX([Value]) FROM ( SELECT a.date1 as [Value] UNION ALL SELECT a.date2 UNION ALL SELECT a.date3 UNION ALL SELECT a.date4 ) x ) b |
12 янв 18, 10:48 [21100331] Ответить | Цитировать Сообщить модератору |
uaggster Member Откуда: Сообщений: 960 |
create table #table1(id int identity,repdate datetime, date1 datetime,date2 datetime,date3 datetime,date4 datetime) insert #table1 select '20180501','20171226','20180326','20180626','20180926' union all select '20180501','20170823','20171123','20180223','20180523' Select a.id, Min(t.[date]) [min_date] from #table1 a Cross apply (Values (a.date1), (a.date2), (a.date2), (a.date3)) t ([date]) Where a.repdate > t.[date] Group by a.id |
12 янв 18, 10:51 [21100347] Ответить | Цитировать Сообщить модератору |
uaggster Member Откуда: Сообщений: 960 |
Пардон, конечно:Values (a.date1), (a.date2), (a.date3), (a.date4) |
12 янв 18, 10:59 [21100397] Ответить | Цитировать Сообщить модератору |
Евгенич Member Откуда: Сообщений: 269 |
Всем спасибо! Сделал через unpivot:select top 1 with ties id,repdate,column_name,(date_) from #table1 unpivot( date_ for column_name in ([date1],[date2],[date3],[date4]) ) as test where date_>repdate order by ROW_NUMBER() over (partition by id order by date_ ) |
12 янв 18, 11:12 [21100488] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6801 |
Евгенич,
этот день нормальным уже не будет |
||
12 янв 18, 11:15 [21100521] Ответить | Цитировать Сообщить модератору |
СегодняПятница
Guest |
TaPaK, Так ведь сегодня же пятница, все только начинается |
12 янв 18, 11:34 [21100650] Ответить | Цитировать Сообщить модератору |
uaggster Member Откуда: Сообщений: 960 |
А теперь сравни планы. С моим, например. |
||
12 янв 18, 13:22 [21101168] Ответить | Цитировать Сообщить модератору |
Руслан Дамирович Member Откуда: Резиновая нерезиновая Сообщений: 940 |
заметил, что PIVOT/UNPIVOT быстрее работают нежели аналогичный код - возможно, плацебо :) а вот TOP WITH TIES - это, конечно, зря... |
||||
12 янв 18, 13:57 [21101341] Ответить | Цитировать Сообщить модератору |
Евгенич Member Откуда: Сообщений: 269 |
Не умею читать планы от слова ваапще. Можете тыкнуть пальцем, чем мой хуже вашего? Скрин приложил. К сообщению приложен файл. Размер - 113Kb |
||||
12 янв 18, 14:13 [21101442] Ответить | Цитировать Сообщить модератору |
Massa52 Member Откуда: Сообщений: 382 |
Евгенич,create table #table1(id int identity,repdate datetime, date1 datetime,date2 datetime,date3 datetime,date4 datetime) insert #table1 select '20180501','20171226','20180326','20180626','20180926' union all select '20180501','20170823','20171123','20180223','20180523' Select id, repdate ,CASE WHEN date1 < date2 AND date1 < date3 AND date1 < date4 THEN date1 WHEN date2 < date3 AND date2 < date4 THEN date2 WHEN date3 < date4 THEN date3 ELSE date4 END minDate from #table1 |
12 янв 18, 14:34 [21101644] Ответить | Цитировать Сообщить модератору |
x_sql_x
Guest |
Евгенич,select id, ( select min (dt) from (values (date1), (date2), (date3), (date4)) t (dt) where dt > repdate ) as min_date from #table1 |
12 янв 18, 14:38 [21101677] Ответить | Цитировать Сообщить модератору |
uaggster Member Откуда: Сообщений: 960 |
Как минимум дополнительная сортировка и сиквенс |
||||
12 янв 18, 16:27 [21102210] Ответить | Цитировать Сообщить модератору |
Massa52 Member Откуда: Сообщений: 382 |
Евгенич,create table #table1(id int identity,repdate datetime, date1 datetime,date2 datetime,date3 datetime,date4 datetime) insert #table1 select '20180501','20171226','20180326','20180626','20180926' union all select '20180501','20170823','20171123','20180223','20180523'; DECLARE @maxDate DATE = '20990101'; -- любая заоблачная дата ;WITH c AS -- отсекаем даты <= repdate ( Select id, repdate ,CASE WHEN date1 <= repdate THEN @maxDate ELSE date1 END date1 ,CASE WHEN date2 <= repdate THEN @maxDate ELSE date2 END date2 ,CASE WHEN date3 <= repdate THEN @maxDate ELSE date3 END date3 ,CASE WHEN date4 <= repdate THEN @maxDate ELSE date4 END date4 from #table1 ) Select id, repdate ,CASE WHEN date1 < date2 AND date1 < date3 AND date1 < date4 THEN date1 WHEN date2 < date3 AND date2 < date4 THEN date2 WHEN date3 < date4 THEN date3 ELSE date4 END minDate from c |
12 янв 18, 19:06 [21102802] Ответить | Цитировать Сообщить модератору |
Евгенич Member Откуда: Сообщений: 269 |
Всем спасибо! |
15 янв 18, 16:08 [21108292] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |