【问题标题】:How to get the week number, start date and end date of Compelete year in SQL Server?如何在SQL Server中获取完整年份的周数、开始日期和结束日期?
【发布时间】:2019-11-07 10:28:38
【问题描述】:

如何获取全年的完整周数、开始日期和结束日期。

注意

  1. 每周从周日到周六开始

  2. 在同一时间第 1 周(例如:01-01-2020 到 04-01-2020)和上周应该是(例如:27-12-2020 到 31-12-2020)

预期结果

WeekNo  WeekStartDate   WeekEndDate
===================================
   1    2019-01-01      2019-01-05
   2    2019-01-06      2019-01-12
   3    2019-01-13      2019-01-19
   4    2019-01-20      2019-01-26
   5    2019-01-27      2019-02-02
   6    2019-02-03      2019-02-09
   7    2019-02-10      2019-02-16
   8    2019-02-17      2019-02-23
   9    2019-02-24      2019-03-02
   ...
   ...upto end of the year

其实这个我也试过rextester

【问题讨论】:

  • 您认为今年的最后一周是哪一周(从 2019 年 12 月 29 日开始,周日->周六)?你的一年可以有 53 周吗?
  • @Martin 是的,你是对的。可能是 53 周(例如:第 53 周 = 从 '29/12/2019' 到 '31/12/2019')

标签: sql sql-server date week-number


【解决方案1】:

如果您只对2019 年感兴趣,那么下面的代码将完全符合您的要求:

DECLARE @weekNum INT = 1;

WITH Weeks AS (
    SELECT @weekNum AS WeekNo
    UNION ALL
    SELECT WeekNo + 1 FROM Weeks WHERE WeekNo + 1 <= 53
)
SELECT  WeekNo,
        CASE
          WHEN WeekStartDate < '2019-01-01' THEN CONVERT(DATE, '2019-01-01')
          ELSE CONVERT(DATE, WeekStartDate)
        END AS WeekStartDate,
        CASE
          WHEN WeekEndDate > '2019-12-31' THEN CONVERT(DATE, '2019-12-31')
          ELSE CONVERT(DATE, WeekEndDate)
        END AS WeekEndDate
  FROM  (
        SELECT  WeekNo,
                DATEADD(WEEK, WeekNo - 1, '2018-12-30') AS WeekStartDate,
                DATEADD(WEEK, WeekNo - 1, '2019-01-05') AS WeekEndDate
          FROM  Weeks
        ) a

输出:

WeekNo  WeekStartDate   WeekEndDate
1       2019-01-01      2019-01-05
2       2019-01-06      2019-01-12
3       2019-01-13      2019-01-19
4       2019-01-20      2019-01-26
5       2019-01-27      2019-02-02
6       2019-02-03      2019-02-09
7       2019-02-10      2019-02-16
8       2019-02-17      2019-02-23
...
51      2019-12-15      2019-12-21
52      2019-12-22      2019-12-28
53      2019-12-29      2019-12-31

编辑以下关于变量开始和结束日期的 OP 评论

根据 OP 关于不同开始和结束日期的评论,我重新审视了代码并使其可以在任何两个日期之间工作:

DECLARE @startDate DATE = CONVERT(DATE, '2019-01-01');
DECLARE @endDate DATE = CONVERT(DATE, '2019-12-31');
DECLARE @weekNum INT = 1;

WITH Weeks AS (
    SELECT @weekNum AS WeekNo
    UNION ALL
    SELECT WeekNo + 1 FROM Weeks WHERE WeekNo + 1 <= DATEDIFF(WEEK, @StartDate, @EndDate) + 1
)
SELECT  WeekNo,
        CASE
          WHEN WeekStartDate < @startDate THEN @startDate
          ELSE CONVERT(DATE, WeekStartDate)
        END AS WeekStartDate,
        CASE
          WHEN WeekEndDate > @endDate THEN @endDate
          ELSE CONVERT(DATE, WeekEndDate)
        END AS WeekEndDate
  FROM  (
        SELECT  WeekNo,
                DATEADD(WEEK, WeekNo - 1, OffsetStartDate) AS WeekStartDate,
                DATEADD(WEEK, WeekNo - 1, OffsetEndDate) AS WeekEndDate
          FROM  Weeks
            INNER JOIN  (
                        SELECT  CASE
                                    WHEN DATEPART(WEEKDAY, @startDate) = 1 THEN @startDate
                                    ELSE DATEADD(DAY, 1 - DATEPART(WEEKDAY, @startDate), @startDate)
                                END AS OffsetStartDate,
                                CASE
                                    WHEN DATEPART(WEEKDAY, @startDate) = 1 THEN DATEADD(DAY, 6, @startDate)
                                    ELSE DATEADD(DAY, 7 - DATEPART(WEEKDAY, @startDate), @startDate)
                                END AS OffsetEndDate
                        ) a ON 1 = 1
        ) a

只需修改 @startDate@endDate 即可反映所需的开始和结束日期。字符串的格式为YYYY-MM-DD

这将输出两个日期之间的可变周数,从指定日期开始和结束(根据需要创建部分周)。希望按照要求。

【讨论】:

  • 你几乎是正确的。但是用户参数是一个StartDate和EndDate,所以它可以像这样StartDate = 01-01-2017和EndDate = 31-12-2023
  • @Liamneesan 啊,我误解了开始和结束日期可以是可变的和不同年份的要求。我再看看
  • @Liamneesan 我已经用一种适用于任何日期范围的更全面的方法更新了答案。
【解决方案2】:

稍微更新马丁的上述回答。您可以根据自己的喜好传递@startDate 和@endDate。

DECLARE @startDate DATETIME = '2019-01-01'
DECLARE @endDate DATETIME = '2021-01-01'
DECLARE @totalWeeks BIGINT= NULL

SELECT @totalWeeks =datediff(ww,@startdate,@enddate)

DECLARE @weekNum INT = 1;
WITH Weeks AS (
    SELECT @weekNum AS WeekNo
    UNION ALL
    SELECT WeekNo + 1 FROM Weeks WHERE WeekNo + 1 <= @totalWeeks
)

SELECT  WeekNo,
        CASE
          WHEN WeekStartDate < @startDate THEN CONVERT(DATE, '2019-01-01')
          ELSE CONVERT(DATE, WeekStartDate)
        END AS WeekStartDate,
        CASE
          WHEN WeekEndDate > @endDate THEN CONVERT(DATE, '2019-12-31')
          ELSE CONVERT(DATE, WeekEndDate)
        END AS WeekEndDate
  FROM  (
        SELECT  WeekNo,
                DATEADD(WEEK, WeekNo - 1, @startDate) AS WeekStartDate,
                DATEADD(WEEK, WeekNo - 1, @endDate) AS WeekEndDate
          FROM  Weeks
        ) a
    OPTION (MAXRECURSION 1000);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 2010-11-19
    相关资源
    最近更新 更多