我有约会,我想要检索日期。
我有表LeaveMaster:
ID LeaveDate
1 23/09/2015
1 24/09/2015
1 25/09/2015
1 27/09/2015
1 29/09/2015
1 30/09/2015
1 01/10/2015
1 02/10/2015
1 04/10/2015
结果应为:
ID StartDate EndDate
1 23/09/2015 25/09/2015
1 27/09/2015 27/09/2015
1 29/09/2015 02/10/2015
1 04/10/2015 04/10/2015
如何解决这个问题?
答案 0 :(得分:2)
查找连续值的技巧是通过从值中减去记录位置来构建组键。然后按该键分组并显示其最小值和最大值。
select id, min(leavedate) as startdate, max(leavedate) as enddate
from
(
select
id,
leavedate,
dateadd(day, - row_number() over (partition by id order by leavedate), leavedate)
as groupkey
from leavemaster
) dates
group by id, groupkey, datepart(year, leavedate), datepart(month, leavedate);
在您的示例中,您显示您还需要新月份的新范围,因此我将datepart(year, leavedate), datepart(month, leavedate)
添加到GROUP BY子句中。如果这只是一个错误,请删除它。
单独执行内部查询以查看其工作原理。
答案 1 :(得分:0)
您可以使用以下查询:
SELECT ID,
MIN(LeaveDate) AS StartDate,
MAX(LeaveDate) AS EndDate
FROM (
SELECT ID, LeaveDate,
DATEDIFF(d, '19000101', LeaveDate) -
ROW_NUMBER() OVER (ORDER BY LeaveDate) AS grp
FROM mytable ) AS t
GROUP BY ID, grp
grp
用于标识连续 LeaveDate
值的行切片。在GROUP BY
子句中使用此字段,我们可以在每个切片上执行聚合函数并获取开始/结束日期。
注意:这适用于与连续 LeaveDate
值相关的时间间隔。它不会识别由于月份变化导致的间隔分割。
答案 2 :(得分:0)
这是我在T-Sql中使用游标和临时表快速掀起的东西。当然,这不是最有效的解决方案,但可以解决问题。
DECLARE @date DATE
DECLARE @lastdate DATE
DECLARE @spantbl TABLE(StartDate date, EndDate date)
DECLARE db_cursor CURSOR FOR
SELECT LeaveDate
FROM LeaveMaster
ORDER BY LeaveDate
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @date
INSERT INTO @spantbl VALUES(@date,NULL)
SET @lastdate = @date
WHILE @@FETCH_STATUS = 0
BEGIN
IF DATEDIFF(d,@lastdate,@date) > 1
BEGIN
UPDATE @spantbl SET EndDate = @lastdate WHERE EndDate IS NULL
INSERT INTO @spantbl VALUES(@date,NULL)
END
SET @lastdate = @date
FETCH NEXT FROM db_cursor INTO @date
END
UPDATE @spantbl SET EndDate = @lastdate WHERE EndDate IS NULL
SELECT *
FROM @spantbl
CLOSE db_cursor
DEALLOCATE db_cursor
而且,我不是专业人士。刚刚学习了游标并将它们用于:)