好吧,在这里忍受我。我们将构建一个代表本月的临时日历表,包括该月之前和之后属于您定义的一周(星期一 - 星期日)的天数。我做了很多步骤来尝试使过程清晰,但在这种情况下我可能并不擅长这一点。
然后,我们可以生成不同周的范围,您可以使用它加入您的其他表格。
SET DATEFIRST 7;
SET NOCOUNT ON;
DECLARE @today SMALLDATETIME, @fd SMALLDATETIME, @rc INT;
SELECT @today = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0), -- today
@fd = DATEADD(DAY, 1-DAY(@today), @today), -- first day of this month
@rc = DATEPART(DAY, DATEADD(DAY, -1, DATEADD(MONTH, 1, @fd)));-- days in month
DECLARE @thismonth TABLE (
[date] SMALLDATETIME,
[weekday] TINYINT,
[weeknumber] TINYINT
);
;WITH n(d) AS (
SELECT TOP (@rc+12) DATEADD(DAY, ROW_NUMBER() OVER
(ORDER BY [object_id]) - 7, @fd) FROM sys.all_objects
)
INSERT @thismonth([date], [weekday]) SELECT d, DATEPART(WEEKDAY, d) FROM n;
DELETE @thismonth WHERE [date] < (SELECT MIN([date]) FROM @thismonth WHERE [weekday] = 2)
OR [date] > (SELECT MAX([date]) FROM @thismonth WHERE [weekday] = 1);
;WITH x AS ( SELECT [date], weeknumber, rn = ((ROW_NUMBER() OVER
(ORDER BY [date])-1) / 7) + 1 FROM @thismonth ) UPDATE x SET weeknumber = rn;
- 现在,给出所有这些的最终查询(我只是将其分解以摆脱垂直滚动条):
;WITH ranges(w,s,e) AS (
SELECT weeknumber, MIN([date]), MAX([date]) FROM @thismonth GROUP BY weeknumber
)
SELECT [week] = CONVERT(CHAR(10), r.s, 120) + ' - ' + CONVERT(CHAR(10), r.e, 120)
--, SOMETHING , other columns from STATISTICS_?
FROM ranges AS r
-- LEFT OUTER JOIN dbo.STATISTICS_ AS s
-- ON s.TIME_ >= r.s AND s.TIME_ < DATEADD(DAY, 1, r.e)
-- comment this out if you want all the weeks from this month:
WHERE w = (SELECT weeknumber FROM @thismonth WHERE [date] = @today)
GROUP BY r.s, r.e --, SOMETHING
ORDER BY [week];
带有 WHERE 子句的结果:
week
-----------------------
2012-05-14 - 2012-05-20
没有 WHERE 子句的结果:
week
-----------------------
2012-04-30 - 2012-05-06
2012-05-07 - 2012-05-13
2012-05-14 - 2012-05-20
2012-05-21 - 2012-05-27
2012-05-28 - 2012-06-03
请注意,我故意选择了 YYYY-MM-DD。您应该避免像 M/D/Y 这样的区域格式,尤其是对于输入和显示。无论您认为您的受众有多么有针对性,总会有人认为 2012 年 5 月 7 日是 7 月 5 日,而不是 5 月 7 日。使用 YYYY-MM-DD 没有任何歧义。