在 SQL Server 中生成周末日期

Posted

技术标签:

【中文标题】在 SQL Server 中生成周末日期【英文标题】:Generating weekending dates in SQL Server 【发布时间】:2021-09-23 19:10:33 【问题描述】:

我在 Microsoft SQL Server Management Studio 工作。我想为不同的 ID 及其不同的时间范围生成所有周末日期(星期六)。

这是我的数据的样子:

ID   minDate    MaxDate
-------------------------
101  5/16/2020  9/25/2021
102  8/7/2021   8/21/2021
103  5/1/2021   9/26/2021

对于ID = 101,我想返回从 2020 年 5 月 16 日、2020 年 5 月 23 日、2020 年 5 月 30 日、2020 年 6 月 6 日开始的所有一周结束日期(星期六)。 . 一直到 2021 年 9 月 25 日。

我需要为所有不同的 ID 做同样的事情。

提前谢谢你!

【问题讨论】:

我建议您对日历表进行一些研究。一个表格,可以针对每一天(包括周末)预先计算一大堆有用的属性。如果您正在执行基于日历的逻辑,您最终可能需要一个日历表。 谢谢@Nick.Mcdermaid。由于我将那个输出用于我的 Power BI 报告,Power BI 中的维度日历表会做同样的事情吗?我只是不知道如何在 power bi 中应用日历表的逻辑。 可能会,但您将在 M 或 DAX 中构建逻辑,而不是 SQL。选择你的毒药 【参考方案1】:

..fiddle..

select *, dateadd(week, nm.rn-1, dateadd(day, 7-datepart(weekday, dateadd(day, @@datefirst,mindate)), mindate)) as _Saturday
from
(
values
(101, cast('20200516' as date), cast('20210925' as date)),
(102, '20210708', '20210822'),
(103, '20210501', '20210926')
) as t(id,mindate,maxdate)
join
(
    --tally..max 1000 weeks
    select row_number() over(order by @@spid) as rn
    from (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) as a(n)
    cross join (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) as b(n)
    cross join (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) as c(n)
) as nm on nm.rn <= datediff(week, mindate, maxdate)+1
where t.maxdate >= dateadd(week, nm.rn-1, dateadd(day, 7-datepart(weekday, dateadd(day, @@datefirst,mindate)), mindate))
order by t.id, nm.rn;

【讨论】:

嗨@Iptr!非常感谢您的快速回复。你介意告诉我,我是否必须像你为 ID 101 所做的那样,将演员表作为每一行的日期吗? ..@XiaofanChen .. 如果 min/maxdate 列是 date(time) 数据类型,则不需要 cast()。该代码可以与 char 列一起使用(在 datediff&add() 函数中隐式转换为日期时间),但最好是明确的..例如 03/04/2021 是 4 月 3 日还是 3 月 4 日?如果是 char min/maxdate 列,最好使用 convert(date,column,style) 而不是 cast()。 感谢您的解释!我能够进行一些调整,让您的查询在我的桌子上工作。天哪,它就像魔术一样工作!非常感谢!! @lptr

以上是关于在 SQL Server 中生成周末日期的主要内容,如果未能解决你的问题,请参考以下文章

计算连续日期,不包括 SQL 中的周末

访问 SQL 减去日期,不包括周末

如何在 SQL Server 查询中排除周末?

按连续日期分组,忽略 SQL 中的周末

如果日期值在周末,则重置日期值

SQL 排除周末和公共/银行假日