如何结合PARTITION与CASE语句?CASE字段返回空值排查
问题原因分析
你的SQL返回空值的核心原因是:你只保留了每个工单的第一条事件记录(rn=1),但这条记录的key不一定是22820430。当第一条记录的key不匹配时,CASE语句返回NULL,后续的MAX()聚合自然也得不到有效值。
因为你的需求是把工单的不同key字段转成列,需要聚合该工单下所有相关事件记录,而不是只取第一条记录。
修正后的SQL写法
根据你的需求,这里提供两种常用的实现方式:
方式1:提取工单所有对应key的值(存在即取)
如果只要工单存在某个key的记录,就提取其对应值(同一key有多条记录时取任意一个,这里用MAX()确保非空):
SELECT te.ticket_id, MIN(te.created_at) AS ticket_created_at, -- 取工单最早的创建时间,对应你原逻辑的rn=1的时间 MAX(CASE WHEN te.key = 22820430 THEN te.value END) AS plan_tier, MAX(CASE WHEN te.key = 'status' THEN te.value END) AS status, MAX(CASE WHEN te.key = 'type' THEN te.value END) AS ticket_type FROM ticket_events te WHERE te.created_at > '2023-06-01' GROUP BY te.ticket_id ORDER BY ticket_created_at DESC;
方式2:提取每个key的最新记录值
如果需要取每个key对应工单的最新事件值(按created_at排序取最新):
WITH ranked_events AS ( SELECT ticket_id, created_at, key, value, -- 按工单+key分区,按时间倒序排,取最新的一条 ROW_NUMBER() OVER (PARTITION BY ticket_id, key ORDER BY created_at DESC) AS rn FROM ticket_events WHERE created_at > '2023-06-01' ) SELECT ticket_id, MAX(created_at) AS ticket_created_at, -- 工单的最新事件时间 MAX(CASE WHEN key = 22820430 THEN value END) AS plan_tier, MAX(CASE WHEN key = 'status' THEN value END) AS status, MAX(CASE WHEN key = 'type' THEN value END) AS ticket_type FROM ranked_events WHERE rn = 1 -- 只保留每个key的最新记录 GROUP BY ticket_id ORDER BY ticket_created_at DESC;
关键说明
- 去掉了原SQL中只取第一条记录的过滤条件,改为对整个工单的事件记录进行聚合,确保能捕获到所有目标
key的值。 - 如果你需要严格保留原逻辑中“取工单最早创建时间”的需求,方式1中的
MIN(te.created_at)可以替换为原SQL的子查询方式获取对应时间,但核心是不要过滤掉工单的其他事件记录。
内容的提问来源于stack exchange,提问作者user22249735
相关产品推荐
相关产品推荐

