分组时,选择日期时间范围之外的最高值

时间:2016-10-21 11:10:53

标签: sql sql-server select grouping

我有一个包含四列的表格:

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检索为ID为1的EndDateTime2015-05-31 09:44:00.000作为ID为2的EndDateTime等,因为它是所选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

3 个答案:

答案 0 :(得分:0)

检查是否有帮助。

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

答案 1 :(得分:0)

使用排名来获得所需内容。这是下面的一个工作示例。

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

答案 2 :(得分:0)

在计算lag()之前,不要使用@StartDateTime限制数据

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;