SQL行转列实现:将患者检测记录转换为宽表结构
解决行转列后行数不符合预期的问题
你遇到的核心问题是:仅使用CASE语句只会逐行生成结果,不会自动合并同一患者的多条测试记录,因此返回行数等于原表中测试记录的总数,而非患者数量。
解决方案:结合GROUP BY与聚合函数
要实现每个患者一行的结果,必须通过GROUP BY patient_id将同一患者的所有记录分组,再用聚合函数(如MAX/MIN)提取每组内各测试项的对应值。示例SQL如下:
SELECT patient_id, -- 映射A11到clinic_test列 MAX(CASE WHEN test_id = 'A11' THEN test_name ELSE NULL END) AS clinic_test, -- 映射A12到lab_test列 MAX(CASE WHEN test_id = 'A12' THEN test_name ELSE NULL END) AS lab_test, -- 映射A13到radio_test列 MAX(CASE WHEN test_id = 'A13' THEN test_name ELSE NULL END) AS radio_test FROM patient_tests GROUP BY patient_id;
为什么用MAX?
由于同一患者的同一test_id通常只会对应一条test_name,MAX会自动忽略NULL值,仅保留该测试项的有效名称。如果存在同一患者同一test_id有多条记录的情况,可根据业务需求替换为MIN(取最早名称)或结合时间字段的聚合逻辑(如取最新记录)。
处理重复记录
如果原表存在重复的patient_id + test_id组合,建议先通过子查询去重,再进行分组:
SELECT patient_id, MAX(CASE WHEN test_id = 'A11' THEN test_name ELSE NULL END) AS clinic_test, MAX(CASE WHEN test_id = 'A12' THEN test_name ELSE NULL END) AS lab_test, MAX(CASE WHEN test_id = 'A13' THEN test_name ELSE NULL END) AS radio_test FROM ( -- 去重同一患者同一测试项的重复记录 SELECT DISTINCT patient_id, test_id, test_name FROM patient_tests ) AS distinct_tests GROUP BY patient_id;
内容的提问来源于stack exchange,提问作者A Saraf
相关产品推荐
相关产品推荐

