查找连续开始/结束日期列之间的日期差距

时间:2015-10-27 19:19:22

标签: sql-server date

我有一个名为periodDefinition的表,其中包含rowNum,periodSeq,startDate,endDate列。我试图编写一个SQL查询来查找一行的endDate和下一行的startDate之间的差距。现在它正在看到一个"差距"如果下一行的startDate与上一行的endDate完全相同。

大多数建议似乎是创建一个日历临时表并对其进行双重检查,但由于工作限制策略,我不能这样做。感谢您提出的任何建议。

示例数据:

rowNum:1,periodSeq:1,startDate:09/01/2014,endDate:09/30/2014

rowNum:2,periodSeq:2,startDate:10/01/2014,endDate:10/30/2014

rowNum:3,periodSeq:4,startDate:11/01/2014,endDate:2014年11月30日

测试查询:

SELECT endDate, startDate
FROM
(
    SELECT DISTINCT startDate, ROW_NUMBER() OVER (ORDER BY startDate) RN
    FROM dbo.PeriodDefinition T1
    WHERE
        NOT EXISTS (
            SELECT *
            FROM dbo.PeriodDefinition T2
            WHERE T1.startDate > T2.startDate AND T1.startDate < T2.endDate
        )
    ) T1
JOIN (
    SELECT DISTINCT endDate, ROW_NUMBER() OVER (ORDER BY endDate) RN
    FROM dbo.PeriodDefinition T1
    WHERE
        NOT EXISTS (
            SELECT *
            FROM dbo.PeriodDefinition T2
            WHERE T1.endDate > T2.startDate AND T1.endDate < T2.endDate
        )
 ) T2
 ON T1.RN - 1 = T2.RN
WHERE
 endDate < startDate

结果:

endDate:2014-09-30,startDate,2014-01-01

endDate:2014-09-30,startDate:2014-11-01

endDate:2014-10-30,startDate:2014-12-01

期望的结果:

endDate:2014-10-30,startDate:2014-11-01

2 个答案:

答案 0 :(得分:2)

假设rowNum是连续的,没有间隙。

这是获得理想结果的简单方法:

SELECT t1.EndDate, t2.StartDate
FROM PeriodDefinition t1
INNER JOIN PeriodDefinition t2
  ON t1.rowNum=t2.rowNum - 1
WHERE DATEDIFF(day, t1.EndDate, t2.StartDate)>1

答案 1 :(得分:0)

如果您对获取缺失日期感兴趣,可以使用递归cte来执行此类操作。

global_var=""

_DBINFO(){

    content=$(
        curl  -su $AUTH https://<balla bla >/databases |
        jq -c 'map(select(.plan.name != "Sandbox")) | .[] | {id, name}'
    )

    while  read -r db
    do
        idb=$(echo "$db" | jq -r '.id')
        name=$(echo "$db" | jq -r '.name')
        if [[ $name = '<bla>' ]]; then
            global_var=$(echo "<bla value>")
        fi
    done <<<"$content"

}

SQL Fiddle

如果您只想使用类似于您的查询,则可以使用

WITH cte AS (
    SELECT  MIN(startDate) startDate,
            MAX(startDate) endDate
    FROM    SampleData
    UNION ALL
    SELECT  DATEADD(day, 1, startDate),
            endDate
    FROM    cte 
    WHERE   DATEADD(day, 1, startDate) <= endDate
)

SELECT  cte.startDate 
FROM    cte
        LEFT JOIN SampleData s ON cte.startDate BETWEEN s.startDate AND s.endDate
WHERE   s.startDate IS NULL 
OPTION (MAXRECURSION 0);

SQL Fiddle

我看到您的查询问题是您没有在SELECT endDate, startDate FROM (SELECT startDate, ROW_NUMBER () OVER (ORDER BY startDate) RN FROM PeriodDefinition T1 ) T1 JOIN (SELECT endDate, ROW_NUMBER () OVER (ORDER BY endDate) RN FROM PeriodDefinition T1 ) T2 ON T1.RN - 1 = T2.RN WHERE endDate + 1 < startDate

中的endDate中添加1