Vertica SQL查询:保留无预约患者Null值并提取唯一后续预约
你的SQL语句不符合需求,存在以下问题:
- 语法错误:
select distinct后未指定查询列,无法正常执行。 - 逻辑偏差:当患者存在未来预约时,
or next_appointment is null会把该患者的next_appointment为Null的记录也筛选出来,违反了“有后续预约的患者不提取Null值”的要求。 - 空值判断错误:SQL中不能用
=判断Null值,当患者没有未来预约时,子查询返回Null,a.next_appointment = null的结果为未知,只会通过or条件带出Null记录,但这同时会污染有未来预约的患者的结果集。
推荐的修改方案(Vertica兼容)
最简洁高效的写法是用聚合函数结合条件判断,直接实现需求:
SELECT patient_id, -- 提取每个患者最早的未来预约,无则返回Null MIN(CASE WHEN next_appointment > NOW() THEN next_appointment END) AS next_appointment FROM a GROUP BY patient_id;
逻辑说明:
- 按患者ID分组(
GROUP BY patient_id),确保每个患者只返回一条结果。 CASE WHEN仅保留当前时间之后的预约时间,不符合条件的记录会转为Null。MIN()函数自动忽略Null值,取每组中最早的未来预约时间;如果该组没有符合条件的预约,MIN()直接返回Null,完美匹配“无后续预约的患者保留Null值”的要求。
如果需要保留原表中的其他字段,可以用窗口函数实现:
WITH patient_appointments AS ( SELECT *, -- 对每个患者的未来预约按时间排序,标记出最早的那条 ROW_NUMBER() OVER ( PARTITION BY patient_id ORDER BY CASE WHEN next_appointment > NOW() THEN next_appointment END ASC NULLS LAST ) AS appointment_rank FROM a ) SELECT patient_id, next_appointment, -- 添加你需要保留的其他字段 other_columns FROM patient_appointments WHERE -- 取最早的未来预约,或者该患者无未来预约时保留Null记录 (appointment_rank = 1 AND next_appointment > NOW()) OR (appointment_rank = 1 AND next_appointment IS NULL AND NOT EXISTS ( SELECT 1 FROM patient_appointments pa WHERE pa.patient_id = patient_appointments.patient_id AND pa.next_appointment > NOW() ))
内容的提问来源于stack exchange,提问作者DAJames
相关产品推荐
相关产品推荐

