PostgreSQL查询返回意外结果:st.cust_dbf_id字段返回空值
问题需求与异常说明
需构建查询生成统计结果表,展示全部71个客户画像在总计10个时间周期内各自购买量最高的商品、对应商品信息,以及客户消费热度最高的时间周期。
当前运行查询存在两个问题:
- 仅能返回对应时间周期的热门商品,所有客户相关字段均返回NULL值
- 无法展示可通过id_table关联获取的客户名称
当前账号对该数据库仅有只读权限,需获取问题排查与解决的方向指引。
当前执行SQL代码
select distinct id_table.name as product_name, pb.recruitment_round, count(pb.purchased), st.cust_dbf_id as cust_profile from product_bought pb join id_table on id_table.dbf_id = pb.dbf_id left join shopper_table st on st.cust_dbf_id = id_table.dbf_id where pb.date >= '2022-01-01' and pb.date <= '2022-01-05' and pb.shopping_time = 4 group by id_table."name", pb.recruitment_round, pb.cust_dbf_id order by count(pb.purchased) desc, pb.recruitment_round limit 1;
结果对比
- 预期结果:查询正常返回
st.cust_dbf_id字段的有效值 - 实际结果:
st.cust_dbf_id字段返回全量NULL值
排查与解决方向
1. 修复关联逻辑错误
当前客户表关联条件完全错误:
- 从字段命名判断,
id_table.dbf_id是商品ID(和pb.dbf_id关联取商品名称),st.cust_dbf_id是客户ID,两个字段分属商品、客户两个不同维度,不存在匹配关系,左连自然匹配不到任何客户数据,导致客户字段全为NULL。 - 正确关联逻辑:先确认
product_bought表中存储客户ID的字段名(大概率是pb.cust_dbf_id),用该字段直接关联shopper_table.cust_dbf_id获取客户信息;客户名称如果存在id_table中,需确认id_table是否同时存储商品、客户两类ID映射,若为统一映射表可关联客户ID取对应客户名。
2. 调整分组与统计逻辑适配需求
当前SQL逻辑完全无法满足多维度TopN统计要求:
- 写死了时间过滤条件,仅查询单时间周期数据,无法覆盖10个时间周期范围
- 加了
limit 1仅返回全局销量最高的1条商品数据,无法覆盖71个客户的维度统计 - SELECT中取
st.cust_dbf_id作为客户字段,但GROUP BY中用的是pb.cust_dbf_id,字段引用不一致也会导致结果异常 - 要实现「每个客户+每个时间周期下购买量最高的商品」统计,需使用窗口函数,按
客户ID+时间周期分区,按购买计数倒序排序,取每个分区排名为1的记录即可,无需加全局limit。
3. 只读权限适配
所有调整仅涉及查询语句编写,不需要对库表做任何修改、写入操作,完全符合只读权限要求。
内容的提问来源于stack exchange,提问作者Noah Toomey
相关产品推荐
相关产品推荐

