【问题标题】:Get week start/end dates and week number for weeks starting on Thursday获取从星期四开始的周开始/结束日期和周数
【发布时间】:2018-12-04 00:43:21
【问题描述】:

我有一个现有的项目,它是一份每周报告。它的参数之一是周范围。它工作得很好,但他们需要重新编写报告,而不是在一年的第一天开始一周,他们需要在第一个星期四开始一周并在星期三结束。我有这个问题

SELECT   MIN([DATE]) as StartWeek
            ,MAX([DATE]) as EndWeek
            ,DATENAME(WEEK,Convert(datetime,CONVERT(VARCHAR(10),CONVERT(DATE,[DATE]),101))) as [WEEK]

    FROM [somedb]
    WHERE DATENAME(Year,Convert(datetime,CONVERT(VARCHAR(10),CONVERT(DATE,[DATE]),101))) = 2018
    GROUP BY DATENAME(WEEK,Convert(datetime,CONVERT(VARCHAR(10),CONVERT(DATE,[DATE]),101)))

这个查询的输出是

Start Week    End Week    WEEK
2018-01-01    2018-01-07  1

预期的输出应该是

Start Week                                         End Week    Week
2018-1-4(since its the first thursday of the week) 2018-1-10    1

是的,我可以DATEADD,但周数仍会将 2018-1-8 确认为 WEEK 2

【问题讨论】:

  • 你只想要第一周的日期吗?
  • @SalmanA 全年
  • 查看修改后的答案。

标签: sql sql-server tsql datetime


【解决方案1】:
DECLARE @WeekDay Varchar(500),
        @Add     Int,
        @DATE    Date;

        SET @DATE = '2018-01-01';

        SELECT @WeekDay = DATENAME(DW,@DATE);

        SELECT @Add = CASE
                      WHEN  @WeekDay    =   'Thursday'  THEN 
                      0
                      WHEN  @WeekDay    =   'Friday'    THEN 
                      6
                      WHEN  @WeekDay    =   'Saturday'  THEN 
                      5
                      WHEN  @WeekDay    =   'Sunday'    THEN 
                      4
                      WHEN  @WeekDay    =   'Monday'    THEN 
                      3
                      WHEN  @WeekDay    =   'Tuesday'   THEN 
                      2
                      WHEN  @WeekDay    =   'Wednesday' THEN 
                      1
                  END

SELECT  DATEADD(DD,@Add, CONVERT(DATE,@DATE))   AS WeekStart,
        DATEADD(DD,@Add+6, CONVERT(DATE,@DATE)) AS WeekEnd,
        1                                       AS Week

【讨论】:

  • 这不会返回一年中的第几周。
【解决方案2】:

我们可以首先使用SET DATEFIRST 语句将一周的第一天设置为星期四。这意味着,进一步的计算将需要一个周四到周三的一周,而不是通常的一周。

然后您可以将数据限制为从一年中的第一个星期四开始,最后只需从 WEEK 中减去 1 即可获得所需的输出。

  set datefirst 4 --Set Thursday as first day of the week

  SELECT MIN(dt) as StartWeek, MAX(dt) as EndWeek, DATENAME(WEEK,dt)-1 as [WEEK]
  FROM #tbl
  WHERE YEAR(dt) = 2018
  AND dt >= (select min(dt) from #tbl where datename(WEEKDAY,dt) = 'Thursday')
  GROUP BY DATENAME(WEEk,dt)

如果您从过滤器中删除 AND 条件,您的第一行将是第 0 周,其中包含一年中第一个星期四之前的三天。即便如此,从 2018 年 1 月 4 日开始的那一周仍然是数字 1。

更新:以下内容应该能够调整 2 年内的几周。

set datefirst 4 --Set Thursday as first day of the week

select *, case when datepart(week,d1) > datepart(week,d2) then datepart(week,d1) else datepart(week,d2)-1 end from
(
select d1, max(d2) d2 from
(select t1.dt d1, t2.dt d2
from #tbl t1
inner join #tbl t2 on datediff(day,t1.dt,t2.dt) between 1 and 6
and t1.dt < t2.dt
and datename(weekday, t1.dt) = 'Thursday') s 
group by d1) t
  • 再次将每周开始时间设置为星期四。
  • 接下来,获取数据集中的所有星期四并找到相应的周末。
  • 最后,添加一个检查周是否在同一年 - 如果不是,则取上一年开始日期的周数。这将为您提供您所期望的连续性。

我在这里设置了一个测试:https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=75582819ff0defb7366592f4a89e9604

【讨论】:

  • 2018 年 1 月 1 日 - 2018 年 1 月 3 日应算作上一年的最后一周,因为最后一个星期四是 2017 年 12 月 28 日
  • 所以你希望它的值是 52,而从 1 月 4 日开始的那一周又是值 1?
  • 是的。如果您计算周数,那应该是正确的答案。