根据所使用的关系数据库管理系统 (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;
解释:
- WITH 递归子句定义了名为 DateSeries 的 CTE。
- 在 CTE 中的初始 SELECT 语句中,我们将锚点值设置为开始日期。
- 在递归 SELECT 语句中,我们使用 DATE_ADD 函数将每次迭代的日期递增一天。
- 递归 SELECT 语句中的 WHERE 子句可确保递归继续,直到生成的日期小于结束日期。
- 最后,外部 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中获取日期序列的方法,请在评论中发布