如何用SQL筛选出包含指定列表全部值的医院诊断记录行?
SQL:查找包含指定所有ICD9代码的就诊/患者记录行
嘿,先帮你明确下需求对应的SQL术语——你要做的是分组内的集合包含查询(简单说就是找那些分组里包含指定所有元素的记录),你可以把标题改成这个,这样后续别人搜索的时候更容易找到。
回到你的问题,我猜你要的是两种情况之一:要么找同一次就诊(hadm_id)里同时包含所有指定ICD9代码的所有记录行,要么找某个患者(subject_id)的所有就诊记录里覆盖了所有指定ICD9代码的所有行。我分别给你写对应的SQL:
情况1:筛选同一次就诊包含所有指定ICD9代码的记录
比如你要找同时有5849和4280的就诊的所有记录,用这个:
-- 替换成你的表名,同时修改IN里的代码列表和HAVING的数字 SELECT t.* FROM diagnosis_table t JOIN ( SELECT hadm_id FROM diagnosis_table WHERE icd9_code IN ('5849', '4280') -- 这里放你要匹配的所有ICD9代码 GROUP BY hadm_id -- 这里的数字要和你指定的代码数量一致,确保所有代码都被包含 HAVING COUNT(DISTINCT icd9_code) = 2 ) AS valid_visits ON t.hadm_id = valid_visits.hadm_id;
代码说明:
- 子查询先把包含指定代码的就诊筛选出来,分组后用
COUNT(DISTINCT icd9_code)确保这个就诊确实覆盖了所有指定代码(加DISTINCT是防止同一次就诊重复记录同一个代码导致误判)。 - 最后关联原表,就能拿到这些符合条件的就诊的所有诊断记录。
情况2:筛选患者所有就诊覆盖所有指定ICD9代码的记录
如果你的需求是找那些患者,他们的所有就诊记录里至少出现过每一个指定的ICD9代码(不管是不是同一次就诊),那把分组对象换成subject_id就行:
SELECT t.* FROM diagnosis_table t JOIN ( SELECT subject_id FROM diagnosis_table WHERE icd9_code IN ('5849', '4280') GROUP BY subject_id HAVING COUNT(DISTINCT icd9_code) = 2 ) AS valid_patients ON t.subject_id = valid_patients.subject_id;
进阶写法(针对支持数组的数据库,比如PostgreSQL)
如果用的是PostgreSQL这类支持数组操作的数据库,写法会更直观,用数组包含运算符@>:
SELECT t.* FROM diagnosis_table t JOIN ( SELECT hadm_id FROM diagnosis_table GROUP BY hadm_id -- 检查分组后的ICD9代码数组是否包含指定的数组 HAVING ARRAY_AGG(DISTINCT icd9_code) @> ARRAY['5849', '4280'] ) AS valid_visits ON t.hadm_id = valid_visits.hadm_id;
这样写不用手动数代码数量,更灵活。
内容的提问来源于stack exchange,提问作者dazedviper




