如何在SQL Server中按星期开始日期和星期结束日期按当月的月份编号或月份名称,星期一开始星期一和星期五结束

时间:2015-10-01 18:51:19

标签: sql-server

input.close()

3 个答案:

答案 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