よし、ここで我慢して。週の定義に該当する月の前後の日(月曜日から日曜日)を含む、今月を表す一時的なカレンダーテーブルを作成します。プロセスを明確にするために多くのステップでこれを行いますが、この場合はおそらくそれが得意ではありません。
その後、さまざまな週の範囲を生成し、それを使用して他のテーブルと結合することができます。
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日は5月7日ではなく7月5日だと思っている人が必ずいます。YYYY-MM-DDを使用すると、あいまいさはまったくありません。