【问题标题】:Using a SQL query, how can I select every date within a range?使用 SQL 查询,如何选择范围内的每个日期?
【发布时间】:2014-05-26 03:50:10
【问题描述】:

我正在查询一个支持票证数据库,每张票证都有一个“打开日期”和“关闭日期”列。门票经常保持开放多天,因此我们需要能够提取每天开放的门票数量。
例如,对于 2014 年 4 月 8 日,我们需要知道 4 月 8 日打开了多少张票,再加上 4 月 8 日之前打开但在 4 日凌晨 12:00 仍然打开的未关闭票的总数/8(可能会或可能不会在 4/8 期间或之后关闭)。

这对于单个日期来说似乎很简单,但现在我需要编写一个查询来提取完整​​的日期范围。
例如,我们需要编写一个查询,返回 2014 年 1 月 1 日到 2014 年 4 月 10 日之间的每个日期以及每个日期打开的门票总数(包括打开 0 个门票的日期)。

这是否可能只使用查询或子查询,而不使用任何存储过程或临时数据表?
我们目前正在将数据拉入 Excel 并在那里计算日期统计信息,但 Excel 不是一个可扩展的解决方案,我们希望 SQL 执行这项工作,以便我们可以将此报告迁移到 SSRS(SQL Server Reporting Services)路。

【问题讨论】:

  • I.K. 的回答会让你接近,但它不会给你没有开票的日期。为此,您需要某种日期表,您可以将其外部加入。

标签: sql sql-server date date-range


【解决方案1】:

您的问题对我来说不是很清楚,但是使用 SQLServer 2005 或更高版本(SQLServer 2008 或更好的日期类型)您可以创建日历。这是一种方法

WITH [counter](N) AS
(SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1)
, days(N) AS (SELECT row_number() over (ORDER BY (SELECT NULL)) FROM [counter])
, months (N) AS (SELECT N - 1 FROM days WHERE N < 13)
SELECT DISTINCT CAST(DATEADD(DAY, days.n, 
                             DATEADD(MONTH, months.n, '20131231')
                            ) AS date)
FROM months
     CROSS JOIN days
ORDER BY 1

如果您需要更多年份,只需相应地添加新的 cte

SQLFiddle

【讨论】:

  • 花了一些时间修修补补,但我想出了如何将 CTE 添加到其他年份。 :) 这很棒,因为它没有达到 100 次递归的限制,即使我尝试创建一个长达数年的日期序列。
  • 不需要递归:添加一个类似于months的cte years(N),将新的cte添加到cross join(month cross join days cross join years)并插入新的一级dateadd添加年份
【解决方案2】:

如果没有某种日期表,其中每个可能的日期都包含一行,您就无法做到这一点。创建日期表非常简单,具体取决于您的 RDBMS 和您的要求。

【讨论】:

    猜你喜欢
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 2011-01-05
    • 2017-03-22
    • 2021-10-27
    • 1970-01-01
    相关资源
    最近更新 更多