我一直在寻找一个关于如何对独占日期间隔计数进行分组的示例。
可以这样做的一种方式是:
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)
这只是一个需要调整的可能性的样本。
有没有人有更好的建议如何在不使用上面的临时表的情况下实现这一目标?
...谢谢
答案 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