日期间隔计数

时间:2014-08-04 13:26:02

标签: sql

我一直在寻找一个关于如何对独占日期间隔计数进行分组的示例。

可以这样做的一种方式是:

 DECLARE @tmp TABLE(cnt INT)

 INSERT INTO @tmp(cnt)
 SELECT COUNT(*) AS ProblemCnt
 FROM Problems
 WHERE Closed IS NULL
 AND (DATEDIFF(DAY, Opened, GETDATE()) <=10)

 INSERT INTO @tmp(cnt)
 SELECT COUNT(*) AS ProblemCnt
 FROM Problems
 WHERE Closed IS NULL
 AND (DATEDIFF(DAY, Opened, GETDATE()) >10
    AND DATEDIFF(DAY, Opened, GETDATE()) <=20)

 INSERT INTO @tmp(cnt)
 SELECT COUNT(*) AS ProblemCnt
 FROM Problems
 WHERE Closed IS NULL
 AND (DATEDIFF(DAY, Opened, GETDATE()) >20
     AND DATEDIFF(DAY, Opened, GETDATE()) <=30)

 SELECT cnt FROM @tmp

问题在于它上面所做的方式是它不像所需的那样动态,需要长达300天。 所以,会有很多选择和插入。不太精通。

另外,我一直在看这样的事情:

 dateadd(day, 5 + (datediff(day, 0, Opened) / 5) * 5, 0)

这只是一个需要调整的可能性的样本。

有没有人有更好的建议如何在不使用上面的临时表的情况下实现这一目标?

...谢谢

2 个答案:

答案 0 :(得分:2)

您可以将天数向下(或向上)舍入到最接近的10,然后按此间隔分组:

SELECT  FLOOR(DATEDIFF(DAY, Opened, GETDATE()) / 10.0) * 10 AS Interval,
        COUNT(*) AS ProblemCnt
FROM    Problems
WHERE   Closed IS NULL
AND     Opened >= DATEADD(DAY, -300, CAST(GETDATE() AS DATE))
AND     Opened < GETDATE()
GROUP BY FLOOR(DATEDIFF(DAY, Opened, GETDATE()) / 10.0) * 10;

我也稍微改变了你的where子句,你当前的WHERE子句不是sargable。例如使用

WHERE   DATEDIFF(DAY, Opened, GETDATE()) < 10

表示为每条记录评估函数,并且Opened上的任何索引都不能使用,但是将其切换为

WHERE   Opened >= DATEADD(DAY, -300, CAST(GETDATE() AS DATE))
AND     Opened < GETDATE()

意味着DATEADD在查询开始时被评估一次(因为GETDATE()被视为常量),并且因为正在比较Opened,所以现在可以使用索引。

答案 1 :(得分:1)

可以通过下面的简单循环来完成

DECLARE @tmp TABLE(cnt INT)

DECLARE @T INT 
SET @T = 0

WHILE (@T <=290)
BEGIN

    INSERT INTO @tmp(cnt)
    SELECT COUNT(*) AS ProblemCnt
    FROM Problems
    WHERE Closed IS NULL
    AND (DATEDIFF(DAY, Opened, GETDATE()) >@T
       AND DATEDIFF(DAY, Opened, GETDATE()) <=@T + 10)

    SET @T = @T + 10

END

SELECT cnt FROM @tmp