从SQL查询中获取日期的句点

时间:2015-11-18 07:09:07

标签: sql sql-server database datetime

我有约会,我想要检索日期。

我有表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

如何解决这个问题?

3 个答案:

答案 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值相关的时间间隔。它不会识别由于月份变化导致的间隔分割。

Demo here

答案 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

而且,我不是专业人士。刚刚学习了游标并将它们用于:)