RedShift表按天区间统计记录数返回0,按月正常,查询是否有误?
首先,你的按天查询语法本身是合法的,但返回0的结果大概率和数据类型不匹配或时区差异有关,下面是具体的排查和修复步骤:
1. 先验证日期计算的结果是否符合预期
先单独执行这两个语句,看看输出的日期值是否和你预期的一致:
-- 查看按天计算的起始日期 SELECT current_date - interval '100' day; -- 查看按月计算的起始日期 SELECT current_date - interval '3 months';
然后对比你的main.transaction_data表中tr_date的时间范围:
SELECT MIN(tr_date), MAX(tr_date) FROM main.transaction_data;
如果MAX(tr_date)早于current_date - interval '100' day的结果,那返回0是正常的;但如果MAX(tr_date)在这个区间内,那就要看下面的原因。
2. 检查数据类型匹配问题
RedShift中,current_date返回的是DATE类型(不带时间),而current_date - interval '100' day会自动转换为TIMESTAMP类型(带00:00:00时间后缀)。如果你的tr_date是DATE类型,在比较时会被隐式转换为TIMESTAMP(同样带00:00:00),这时候tr_date > [TIMESTAMP值]不会包含tr_date等于起始日期的记录。
解决办法:把日期计算也转为DATE类型,避免类型转换的歧义:
-- 方法1:RedShift支持DATE直接减整数表示减天数,写法更简洁 SELECT count(*) FROM main.transaction_data WHERE tr_date > current_date - 100; -- 方法2:显式转换为DATE类型 SELECT count(*) FROM main.transaction_data WHERE tr_date > (current_date - interval '100' day)::DATE;
3. 排查时区差异问题
如果你的tr_date存储的是UTC时间,而RedShift集群的时区设置为本地时区(比如东八区、美国东部时间等),current_date会基于集群时区计算,导致按天计算的起始日期对应的UTC时间比你预期的要晚,从而过滤掉所有记录。
解决办法:统一时区进行计算,比如把current_date转为UTC,或者把tr_date转为集群时区:
-- 把current_date转换为UTC时间来计算 SELECT count(*) FROM main.transaction_data WHERE tr_date > (current_date AT TIME ZONE 'UTC') - interval '100' day; -- 或者把tr_date转换为集群时区(替换成你的集群实际时区,比如'Asia/Shanghai') SELECT count(*) FROM main.transaction_data WHERE tr_date AT TIME ZONE 'UTC' AT TIME ZONE 'Asia/Shanghai' > current_date - 100;
4. 尝试使用>=替代>
如果你的tr_date包含起始日期的记录(比如tr_date等于current_date - 100 day),使用>会排除这些记录,改为>=就能包含:
SELECT count(*) FROM main.transaction_data WHERE tr_date >= current_date - interval '100' day;
你可以先从第一步的验证开始,确认日期区间是否真的包含数据,再逐步排查后面的原因,应该就能解决问题了。
内容的提问来源于stack exchange,提问作者samba

