如何在 DB2 中自动获取两个指定日期之间的数据
数据小陈
结论
可以。以 DB2 的 CURRENT DATE 为基准,先算出当月第一天,再据此确定上一个完整 billing cycle 的日期范围。
报表在 3 月 5 日运行时:
- 起始日期:1 月 26 日
- 结束日期:2 月 25 日
- 时间戳筛选的排他上界:2 月 26 日
推荐写法
如果数据字段是 TIMESTAMP,建议采用左闭右开的范围,避免漏掉 2 月 25 日当天带有具体时间的数据:
WITH date_bounds AS
(
SELECT
month_start - 1 MONTH - 6 DAYS AS start_date,
month_start - 3 DAYS AS end_exclusive
FROM
(
SELECT
CURRENT DATE
- (DAY(CURRENT DATE) - 1) DAYS AS month_start
FROM SYSIBM.SYSDUMMY1
) AS x
)
SELECT t.*
FROM your_table AS t
CROSS JOIN date_bounds AS b
WHERE t.transaction_timestamp >= b.start_date
AND t.transaction_timestamp < b.end_exclusive;
假设查询在 3 月 5 日运行,各日期的计算结果为:
month_start = 3 月 1 日
start_date = 3 月 1 日 - 1 MONTH - 6 DAYS = 1 月 26 日
end_exclusive = 3 月 1 日 - 3 DAYS = 2 月 26 日
实际查询范围是:
[1 月 26 日 00:00:00, 2 月 26 日 00:00:00)
这个范围完整覆盖了 1 月 26 日至 2 月 25 日的数据。
如果字段类型是 DATE
如果字段是纯 DATE 类型,也可以用 BETWEEN 包含起止日期:
WITH date_bounds AS
(
SELECT
month_start - 1 MONTH - 6 DAYS AS start_date,
month_start - 4 DAYS AS end_date
FROM
(
SELECT
CURRENT DATE
- (DAY(CURRENT DATE) - 1) DAYS AS month_start
FROM SYSIBM.SYSDUMMY1
) AS x
)
SELECT t.*
FROM your_table AS t
CROSS JOIN date_bounds AS b
WHERE t.transaction_date BETWEEN b.start_date AND b.end_date;
查询在 3 月运行时,两个边界分别是:
start_date = 1 月 26 日
end_date = 2 月 25 日
也可以直接写在 WHERE 中
如果日期边界不需要复用,可以直接写进 WHERE:
SELECT *
FROM your_table
WHERE transaction_timestamp >=
(
CURRENT DATE
- (DAY(CURRENT DATE) - 1) DAYS
- 1 MONTH
- 6 DAYS
)
AND transaction_timestamp <
(
CURRENT DATE
- (DAY(CURRENT DATE) - 1) DAYS
- 3 DAYS
);
注意事项
- 上述计算以报表固定在每月 5 日运行,并读取最近一个已经结束的 billing cycle 为前提。
CURRENT DATE取 DB2 数据库服务器认定的当前日期。如果数据库服务器与业务所在地区的时区不同,需要确认跨月时是否会产生日期偏差。- 对于
TIMESTAMP字段,不要写成:
BETWEEN start_date AND end_date
end_date 转成时间戳后通常是当天的 00:00:00,可能漏掉结束日白天的数据。使用 < end_exclusive 可以避免这个问题。
- 日期范围应直接与数据列比较,不要在列上套用
DATE()等函数。例如,优先使用:
transaction_timestamp >= b.start_date
不要写成:
DATE(transaction_timestamp) >= b.start_date
直接比较通常更有利于 DB2 使用日期或时间戳索引。
- 如果 WebI 使用语义层对象或 Universe 查询,需要确认生成的 SQL 能否保留 CTE。如果不能,可以改用直接写在
WHERE中的版本,或者在 Universe 中创建对应的日期过滤对象。
备注:内容仅供参考。
