MySQL在不使用表列的情况下选择两列之间的范围日期

Posted

技术标签:

【中文标题】MySQL在不使用表列的情况下选择两列之间的范围日期【英文标题】:MySQL Select range date between two columns without using table columns 【发布时间】:2020-11-17 11:02:00 【问题描述】:

在我的 sql 中,我想在不使用表列的情况下获取两个日期之间的日期差异 例如

SELECT BETWEEN '2012-01-10' AND '2012-01-15' as date1;

我必须得到以下日期作为输出 '2012-01-11' '2012-01-12' '2012-01-13' '2012-01-14'

如何编写查询以得到如上的输出

【问题讨论】:

从答案中可以看出,值得考虑升级到 mysql 8。旧版本缺少我们期望现代 RDBMS 提供的功能。 【参考方案1】:
WITH RECURSIVE
cte AS ( SELECT @startdate + INTERVAL 1 DAY `date`
         UNION ALL
         SELECT `date`+ INTERVAL 1 DAY
         FROM cte 
         WHERE `date` < @enddate - INTERVAL 1 DAY )
SELECT * 
FROM cte

fiddle

需要 MySQL 8+。


我的sql版本用的是5.6

最长 1 年

SELECT @startdate + INTERVAL (n3.num * 7 * 7 + n2.num * 7 + n1.num + 1) DAY `date`
FROM  ( SELECT 0 num union select 1 union select 2 union select 3
       union select 4 union select 5 union select 6) n1
JOIN  ( SELECT 0 num union select 1 union select 2 union select 3
       union select 4 union select 5 union select 6) n2
JOIN  ( SELECT 0 num union select 1 union select 2 union select 3
       union select 4 union select 5 union select 6 union select 7) n3
HAVING `date` < @enddate;

fiddle

最大。周期长度为 7 * 7 * 8 = 392 天。

【讨论】:

我的 sql 版本使用 5.6,我尝试了以下查询,但是当我们使用超过 3 个月的日期差异时,它没有返回正确的答案 SELECT '2020-09-01' + INTERVAL a + b DAY AS date_selected FROM (SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) d, (SELECT 0 b UNION SELECT 10 UNION SELECT 20 UNION SELECT 30 UNION SELECT 40) m WHERE '2020-09-01' + INTERVAL a + b DAY @Nishanth my sql version used 5.6 你应该在问题的最开始用大写字母写它。这很关键!无论如何 - 周期长度的实际最大值是多少天? 周期将基于用户的选择。他们最多可以使用 1 年 @Nishanth Variant 为您添加的版本。 @Nishanth 将最后一个子查询扩展到 15 或添加一个数字生成级别子查询(并相应地编辑表达式)。您可以在任何级别使用任何基数 - 只需避免最终数字重复。【参考方案2】:

如果您运行的是 MySQL 8.0,则可以使用递归查询来执行此操作:

with recursive cte as (
    select '2012-01-10' + interval 1 day as dt
    union all 
    select dt + interval 1 day from cte where dt + interval 1 day < '2012-01-15'
)
select * from cte

这会在输入给定的范围内每个日期生成一行。

【讨论】:

@Akina:谢谢。我有时会误认为recursive 关键字,因为有些数据库需要它而其他数据库不需要它:例如 MySQL 需要它,SQL Server 不需要它,在 Postgres 中它是可选的......

以上是关于MySQL在不使用表列的情况下选择两列之间的范围日期的主要内容,如果未能解决你的问题,请参考以下文章

在不使用第三个变量或表的情况下交换表中两列的值

如何在不使用 CONCAT 操作的情况下连接两列 RDBMS 字段[重复]

我可以在不返回条件列的情况下进行左连接吗?

如何使用 VBA 在 Excel 宏中删除具有两列的重复项?

在不选择所需列的情况下加入表或加入表中列的子选择是不是更有效

如何在不转换列的情况下更改 MySQL 中的表(默认)排序规则[重复]