【问题标题】:Finding all dates after a date for a variable number of days查找日期后可变天数的所有日期
【发布时间】:2020-04-29 20:26:31
【问题描述】:

我在表格中有一个日期列表。对于此示例,每个月的第一天。我们称它为带有 endTime 列的表时间段

endTime
1-1-2019
2-1-2019
3-1-2019
4-1-2019

我想查找列表中每个日期后的所有日期 x 天数。假设 x = 4。那么列表应该是:

1-1-2019
1-2-2019
1-3-2019
1-4-2019
2-1-2019
2-2-2019
2-3-2019
2-4-2019
3-1-2019
3-2-2019
3-3-2019
3-4-2019
4-1-2019
4-2-2019
4-3-2019
4-4-2019

我找到了查找日期之间所有日期的解决方案,但是当我尝试将它与日期列表一起使用时,我不断收到 “子查询返回超过 1 个值” 错误。

这是我尝试但不起作用的示例

declare @days DECIMAL = 4
declare @StartDate date = (select convert(varchar, DATEADD(Day, +0, endTime),101) from timeperiod
declare @EndDate date = (select convert(varchar, DATEADD(Day, +@days, endTime),101) from timeperiod;

;WITH cte AS (
    SELECT @StartDate AS myDate
    UNION ALL
    SELECT DATEADD(day,1,myDate) as myDate
    FROM cte
    WHERE DATEADD(day,1,myDate) <=  @EndDate
)
SELECT myDate
FROM cte
OPTION (MAXRECURSION 0)

【问题讨论】:

  • 您将问题标记为 MySQL-relative,但使用 SQL Server 语法...奇怪...
  • 请标记你的sqlserver版本;它可以有一个轴承

标签: sql loops tsql date


【解决方案1】:

这里是一个行生成器,生成 5 行,0 到 4:

WITH rg AS (
   SELECT 0 AS rn
   UNION ALL
   SELECT rg.rn + 1
   FROM   rg
   WHERE  rn < 4
)

在这里,我们将它与您现有的包含月初的表连接起来,并使用 DATEADD 将 rn 天数(介于 0 和 4 之间)添加到 endPeriod。 CROSS JOINing 它导致 timePeriod 中的行每个重复 5 次:

SELECT
  DATEADD(DAY, rg.rn, timePeriod.endTime) as fakeEndTime
FROM
  rg CROSS JOIN timePeriod

当您说“日期后 X 天,说 x = 4”时,我不太清楚 - 对我来说,如果有一天是 2000 年 1 月 1 日,那么 4 天后的日期就是 5 -2000 年 1 月

如果您只想要 Jan 的 1、2、3 和 4,请使用行生成器 &lt; 3 而不是 &lt; 4

【讨论】:

    【解决方案2】:

    已经在 Caius Jard 的递归 cte 上 +1。

    这是另一个使用临时计数表与 CROSS JOIN 相结合的选项

    示例

    Declare @YourTable Table ([endTime] date)
    Insert Into @YourTable Values 
     ('1-1-2019')
    ,('2-1-2019')
    ,('3-1-2019')
    ,('4-1-2019')
    
    Select NewDate = dateadd(DAY,N-1,EndTime)
     From @YourTable A
     Cross Join ( 
                    Select Top (4) N=row_number() over (order by (select null)) 
                     From  master..spt_values N1
                ) B
    

    退货

    NewDate
    2019-01-01
    2019-01-02
    2019-01-03
    2019-01-04
    2019-02-01
    2019-02-02
    2019-02-03
    2019-02-04
    2019-03-01
    2019-03-02
    2019-03-03
    2019-03-04
    2019-04-01
    2019-04-02
    2019-04-03
    2019-04-04
    

    【讨论】:

    • 可能值得一提的是,spt_values 不会在 SQLAzure 上退出,并且需要其他一些“N 行表”。当然,对于像“星期一、星期二和星期四,但不是国定假日”这样的棘手查询,无论如何都要有一个日历/数字表总是一个相当不错的主意!
    猜你喜欢
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    相关资源
    最近更新 更多