#sql #sql-server #select #grouping
#sql #sql-сервер #выберите #группировка
Вопрос:
У меня есть таблица, содержащая четыре столбца:
Id (uniqueidentifier),
Name (varchar),
StartDateTime (datetime),
EndDateTime (datetime)
И два входных параметра:
@StartDateTime (datetime)
@EndDateTime (datetime)
Мой запрос в настоящее время выглядит следующим образом:
SELECT
[Id],
[Name],
MIN([StartDateTime]),
MAX([EndDateTime]),
FROM
[Table]
WHERE
[StartDateTime] BETWEEN @StartDateTime AND @EndDateTime
GROUP BY
[Id],
[Name],
DATEADD(DD, DATEDIFF(DD, 0, [StartDateTime]), 0)
Есть ли способ каким-либо образом также выбрать максимальное значение EndDateTime
в таблице, которое меньше MIN([StartDateTime])
, независимо от способа группировки таблицы? Например. для следующего набора данных, если @StartDateTime = '2016-06-01'
и @EndDateTime = '2016-06-02'
, я бы хотел, чтобы в моем запросе возвращался столбец, который извлекается 2015-05-31 09:07:17.000
как EndDateTime
для идентификатора 1, 2015-05-31 09:44:00.000
как EndDateTime
для идентификатора 2 и т.д., Поскольку он является самым высоким EndDateTime
перед выбранным MIN([StartDateTime])
ID | StartDateTime | EndDateTime
---------------------------------------------------------
1 | 2015-05-31 08:44:59.000 | 2015-05-31 09:07:17.000
2 | 2015-05-31 09:12:06.000 | 2015-05-31 09:44:00.000
3 | 2015-05-31 13:25:47.000 | 2015-05-31 13:34:34.000
4 | 2015-05-31 14:15:54.000 | 2015-05-31 14:24:23.000
1 | 2015-06-01 06:08:47.000 | 2015-06-01 06:10:58.000
2 | 2015-06-01 06:12:05.000 | 2015-06-01 07:24:11.000
3 | 2015-06-01 12:54:53.000 | 2015-06-01 12:55:34.000
4 | 2015-06-01 13:32:18.000 | 2015-06-01 13:33:05.000
Ответ №1:
Проверьте, помогает ли это.
select t.Id, t.Name, minStart, MAX(t.EndDateTime) from #temp t inner join
(select Id, Name, MIN(StartDateTime) minStart from #temp t1 group by Id, Name,
DATEADD(DD, DATEDIFF(DD, 0, starttime), 0))t1
ON t1.minStart = t.StartDateTime
where t.EndTime < t1.minStart
GROUP BY t.Id, t.Name, minStart
Ответ №2:
Используйте ранжирование, чтобы получить то, что вам нужно. Это рабочий пример ниже.
create table #Temp
(
Id int,
Name varchar(10),
StartDate DateTime,
EndDate DateTime
)
insert into #Temp (Id, StartDate, EndDate)
values
(1 , '2015-05-31 08:44:59.000' , '2015-05-31 09:07:17.000' ),
(2 , '2015-05-31 09:12:06.000' , '2015-05-31 09:44:00.000' ),
(3 , '2015-05-31 13:25:47.000' , '2015-05-31 13:34:34.000' ),
(4 , '2015-05-31 14:15:54.000' , '2015-05-31 14:24:23.000' ),
(1 , '2015-06-01 06:08:47.000' , '2015-06-01 06:10:58.000' ),
(2 , '2015-06-01 06:12:05.000' , '2015-06-01 07:24:11.000' ),
(3 , '2015-06-01 12:54:53.000' , '2015-06-01 12:55:34.000' ),
(4 , '2015-06-01 13:32:18.000' , '2015-06-01 13:33:05.000' )
select s.Id, S.EndDate
from (
select ID, StartDate, EndDate, Rank() Over(Partition By Id Order By StartDate asc) as xrank
from #Temp
) s
where s.xrank = 1
drop table #temp
Ответ №3:
Не ограничивайте данные с помощью @StartDateTime до вычисления функции lag()
DECLARE @StartDateTime DATETIME = '2015-06-01' ,
@EndDateTime DATETIME = '2015-06-02';
SELECT ID,sd,ed,ped
FROM (
SELECT [Id],
sd = MIN([StartDateTime]),
ed = MAX([EndDateTime]),
ped = LAG(MAX([EndDateTime])) OVER(PARTITION BY id ORDER BY MIN([StartDateTime]))
FROM(
-- sample data
VALUES (1, CAST('2015-05-31 08:44:59.000' AS DATETIME),CAST('2015-05-31 09:07:17.000' AS DATETIME))
,(2,'2015-05-31 09:12:06.000','2015-05-31 09:44:00.000')
,(3,'2015-05-31 13:25:47.000','2015-05-31 13:34:34.000')
,(4,'2015-05-31 14:15:54.000','2015-05-31 14:24:23.000')
,(1,'2015-06-01 06:08:47.000','2015-06-01 06:10:58.000')
,(2,'2015-06-01 06:12:05.000','2015-06-01 07:24:11.000')
,(3,'2015-06-01 12:54:53.000','2015-06-01 12:55:34.000')
,(4,'2015-06-01 13:32:18.000','2015-06-01 13:33:05.000')
) t(id,StartDateTime,EndDateTime)
WHERE [StartDateTime] <= @EndDateTime
GROUP BY
[Id],
DATEADD(DD, DATEDIFF(DD, 0, [StartDateTime]), 0)
) x
WHERE sd >= @StartDateTime;