卡卡编程网

专注编程技术分享,涵盖开发教程与实战案例

在常用数据库中生成日期序列

根据所使用的关系数据库管理系统 (RDBMS),可以使用不同的方法在两个特定日期之间生成日期序列。我将提供一些流行的RDBMS系统的示例:MySQL,PostgreSQL和Microsoft SQL Server。

请注意,语法可能会因您使用的 RDBMS 的特定版本而略有不同,因此,如果遇到任何问题,应查阅特定版本的文档。

MySQL

旧版 MySQL (5.7.*)
旧的 MySQL 没有生成日期序列的内置函数,因此您可能需要使用临时表或数字表。下面是使用数字表方法的示例:

CREATE TEMPORARY TABLE Numbers (n INT);
-- Insert numbers up to the desired range
INSERT INTO Numbers VALUES (0), (1), (2), ...;  

SELECT 
    DATE_ADD('start_date', INTERVAL n DAY) AS generated_date
FROM Numbers
WHERE 
    DATE_ADD('start_date', INTERVAL n DAY) <= 'end_date';

只需将“start_date”和“end_date”替换为您想要的开始和结束日期,然后在 SQLize.online 上尝试即可。

在现代MySQL 8.0.*中,您可以使用公用表表达式(CTE)在两个特定日期之间生成日期序列。以下是您可以做到这一点的方法:

SET @start_date = '2022-01-01';
SET @end_date = '2022-01-31';

WITH RECURSIVE DateSeries AS (
    SELECT @start_date AS generated_date
    UNION ALL
    SELECT DATE_ADD(generated_date, INTERVAL 1 DAY)
    FROM DateSeries
    WHERE generated_date < @end_date
)
SELECT generated_date
FROM DateSeries;

解释:

  1. WITH 递归子句定义了名为 DateSeries 的 CTE。
  2. 在 CTE 中的初始 SELECT 语句中,我们将锚点值设置为开始日期。
  3. 在递归 SELECT 语句中,我们使用 DATE_ADD 函数将每次迭代的日期递增一天。
  4. 递归 SELECT 语句中的 WHERE 子句可确保递归继续,直到生成的日期小于结束日期。
  5. 最后,外部 SELECT 语句从 CTE 中选择所有生成的日期。

请记住,递归查询可能会占用大量资源,因此请谨慎使用它们,并且仅在必要时使用它们。在此处尝试查询

PostgreSQL

PostgreSQL具有generate_series功能,使这项任务变得容易:

SELECT generate_series('2022-01-01'::date, '2022-01-31'::date, '1 day') AS generated_date;

将“start_date”和“end_date”替换为所需的开始和结束日期。

Microsoft SQL Server

SQL Server也有类似的方法,使用sys.dates系统表和DATEADD函数:

DECLARE @start_date DATE = '2022-01-01'
DECLARE @end_date DATE = '2022-01-31'

SELECT TOP 
    (DATEDIFF(day, @start_date, @end_date) + 1)
    generated_date = DATEADD(day, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @start_date)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;

由于 SQL Server 2022 实现了函数,您也可以以以下方式将其用于生成日期系列:GENERATE_SERIES

SELECT 
    DATEADD(day, value, '2022-01-01') AS Date
FROM GENERATE_SERIES(0, DATEDIFF(day, '2022-01-01', '2022-01-31'))

神谕

SELECT DATE '2022-01-01' + LEVEL - 1 AS generate_series
FROM dual
CONNECT BY LEVEL <= DATE '2022-01-31' - DATE '2022-01-01' + 1

另一种很酷的方法:

SELECT TRUNC (DATE '2023-01-01' + ROWNUM) dt
  FROM DUAL CONNECT BY ROWNUM < 31

如果您知道更多在不同RDBMS中获取日期序列的方法,请在评论中发布

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言