input.close()
答案 0 :(得分:1)
@Rafal正在使用@Month和未记录的系统表' spt_values' (微软可以随时决定改变)。出于长寿目的,我不建议参考此表。
虽然我之前说过这个问题无法真正有效地解决,但我的意思是"这个问题无法有效解决没有一套假设"
我的假设是:
代码:
DECLARE @WeekNo int= 1 DECLARE @Year int=2007
IF @WeekNo = 1
BEGIN
SELECT CASE
WHEN DATEPART(dw,DATEFROMPARTS(@Year,01,01)) = 2 THEN CAST(DATEFROMPARTS(@Year,01,01) AS VARCHAR(MAX))
ELSE CAST('Irrelevant: The week selected is a half-week with either a missing Monday or Friday' AS VARCHAR(MAX))
END AS Week_Start
,CASE
WHEN DATEPART(dw,DATEFROMPARTS(@Year,01,01)) = 2 THEN CAST(DATEFROMPARTS(@Year,01,05) AS VARCHAR(MAX))
ELSE CAST('Irrelevant: The week selected is a half-week with either a missing Monday or Friday' AS VARCHAR(MAX))
END AS Week_End
END
ELSE
BEGIN
SELECT CASE
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 1 THEN DATEADD(dd,1,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 3 THEN DATEADD(dd,-1,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 4 THEN DATEADD(dd,-2,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 5 THEN DATEADD(dd,-3,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 6 THEN DATEADD(dd,-4,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 7 THEN DATEADD(dd,-5,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
END AS Week_Start
,CASE
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 1 THEN DATEADD(dd,4,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 3 THEN DATEADD(dd,3,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 4 THEN DATEADD(dd,2,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 5 THEN DATEADD(dd,1,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 6 THEN DATEADD(dd,-1,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
WHEN DATEPART(dw,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0))) = 7 THEN DATEADD(dd,-2,DATEADD(ww,@WeekNo,DATEADD(yy,DATEDIFF(yy,0,DATEFROMPARTS(@Year,01,01)),0)))
END AS Week_End
END
答案 1 :(得分:0)
此解决方案模仿@Rafal,但使用递归CTE创建一组数字,而不是依赖于master..spt_values。
DECLARE @Year INT = 2015,
@Month INT = 10;
WITH iterator as
(
SELECT 1 as number
UNION ALL
SELECT 1+number
FROM iterator
WHERE number<=31
)
SELECT DISTINCT DATEADD(week, datediff(week, 0, DATEADD(DAY,i.number,DATEFROMPARTS(@Year,@Month,1))), 0) AS weekstart,
DATEADD(week, datediff(week, 0, DATEADD(DAY,i.number,DATEFROMPARTS(@Year,@Month,1))), 4) AS weekend
FROM iterator as i
WHERE DATEPART(MONTH, DATEADD(DAY,i.number,DATEFROMPARTS(@Year,@Month,1))) = @month
答案 2 :(得分:0)
此查询应符合您的期望:
DECLARE @Year INT = 2015,
@Month INT = 10
SELECT DISTINCT DATEADD(week, datediff(week, 0, DATEADD(DAY,sv.number,DATEADD(YEAR,@Year-1900,DATEADD(MONTH,@Month-1,0)))), 0) AS weekstart,
DATEADD(week, datediff(week, 0, DATEADD(DAY,sv.number,DATEADD(YEAR,@Year-1900,DATEADD(MONTH,@Month-1,0)))), 4) AS weekend
FROM master..spt_values sv
WHERE
sv.type = 'P'
AND sv.number <= 31
AND DATEPART(MONTH, DATEADD(DAY,sv.number,DATEADD(YEAR,@Year-1900,DATEADD(MONTH,@Month-1,0)))) = @month