我有一个表,包括创建日期,创建项目的ID以及其他不重要的信息。我想要做的是编写一个查询,该查询总结了在给定日期范围内按周创建的项目。所以如果我有这张桌子:
ID creationdate
-- ------------
1 1/1/2015
2 1/2/2015
3 1/3/2015
4 1/3/2015
5 1/3/2015
6 1/5/2015
7 1/6/2015
如果我要查询2014年12月29日至2015年1月11日的日期范围,我希望看到以下结果:
weekof count
------ -----
12/29/2014 5
1/05/2015 7
有没有办法实现这个目标?
答案 0 :(得分:1)
计算表上累积值的一种方法是创建自联接并使用> =比较运算符连接已连接的字段。
从您的问题看来,您的一周从星期一开始。因此,您还需要计算表中每行的前一个星期一。在我的解决方案中,我使用DATENAME计算了当天的名称,然后从创建日期中减去创建日期过去一周的天数。
最后,我使用FORMAT函数格式化了日期。
CREATE TABLE [dbo].[DateTest] ---Create Test Table DateTest
(
[ID] [int] NULL,
[CreationDate] [datetime] NULL
)
GO
---Insert Values
INSERT INTO
DateTest
VALUES
('1','1/1/2015'),
('2','1/2/2015'),
('3','1/3/2015'),
('4','1/3/2015'),
('5','1/3/2015'),
('6','1/5/2015'),
('7','1/6/2015')
GO
---Perform the calculation
SELECT
FORMAT(t1.StartOfWeek, 'd', 'en-US') as StartOfWeek, ----Render date as mm/dd/yyyy
SUM(t2.CountForWeek) as CumulativeRecordCount
FROM
(
SELECT
(CASE --Determine the most recent preceding Monday, because Monday is defined as the beginning of the week
WHEN DATENAME(dw,CreationDate) = 'Sunday' THEN CreationDate-6
WHEN DATENAME(dw,CreationDate) = 'Saturday' THEN CreationDate-5
WHEN DATENAME(dw,CreationDate) = 'Friday' THEN CreationDate-4
WHEN DATENAME(dw,CreationDate) = 'Thursday' THEN CreationDate-3
WHEN DATENAME(dw,CreationDate) = 'Wednesday' THEN CreationDate-2
WHEN DATENAME(dw,CreationDate) = 'Tuesday' THEN CreationDate-1
ELSE CreationDate
END) AS StartOfWeek,
COUNT(id) AS CountForWeek
FROM
DateTest
GROUP BY
(CASE --Determine the most recent preceding Monday, because Monday is defined as the beginning of the week
WHEN DATENAME(dw,CreationDate) = 'Sunday' THEN CreationDate-6
WHEN DATENAME(dw,CreationDate) = 'Saturday' THEN CreationDate-5
WHEN DATENAME(dw,CreationDate) = 'Friday' THEN CreationDate-4
WHEN DATENAME(dw,CreationDate) = 'Thursday' THEN CreationDate-3
WHEN DATENAME(dw,CreationDate) = 'Wednesday' THEN CreationDate-2
WHEN DATENAME(dw,CreationDate) = 'Tuesday' THEN CreationDate-1
ELSE CreationDate
END)
) AS t1
INNER JOIN --Self Join Table
(
SELECT
(CASE --Determine the most recent preceding Monday, because Monday is defined as the beginning of the week
WHEN DATENAME(dw,CreationDate) = 'Sunday' THEN CreationDate-6
WHEN DATENAME(dw,CreationDate) = 'Saturday' THEN CreationDate-5
WHEN DATENAME(dw,CreationDate) = 'Friday' THEN CreationDate-4
WHEN DATENAME(dw,CreationDate) = 'Thursday' THEN CreationDate-3
WHEN DATENAME(dw,CreationDate) = 'Wednesday' THEN CreationDate-2
WHEN DATENAME(dw,CreationDate) = 'Tuesday' THEN CreationDate-1
ELSE CreationDate
END) AS StartOfWeek,
COUNT(id) AS CountForWeek
FROM
DateTest
GROUP BY
(CASE --Determine the most recent preceding Monday, because Monday is defined as the beginning of the week
WHEN DATENAME(dw,CreationDate) = 'Sunday' THEN CreationDate-6
WHEN DATENAME(dw,CreationDate) = 'Saturday' THEN CreationDate-5
WHEN DATENAME(dw,CreationDate) = 'Friday' THEN CreationDate-4
WHEN DATENAME(dw,CreationDate) = 'Thursday' THEN CreationDate-3
WHEN DATENAME(dw,CreationDate) = 'Wednesday' THEN CreationDate-2
WHEN DATENAME(dw,CreationDate) = 'Tuesday' THEN CreationDate-1
ELSE CreationDate
END)
) AS t2
ON
t1.StartOfWeek >= t2.StartOfWeek --- join t2.startofweek to all t1.startofweek dates greater than or equal to t2.startofweek
GROUP BY
t1.StartOfWeek
StartOfWeek CumulativeRecordCount ------------- --------------------- 12/29/2014 5 1/5/2015 7