MySQL多行转单行多列:用户数据转换需求及问题
MySQL行转列+编码替换解决方案
针对你遇到的ID=12345的多行数据转单行多列、同时替换procedure编码的问题,直接给你能用的SQL写法,再讲清楚之前出错的核心原因:
场景1:每个procedure编码仅对应一条记录
假设你的表名为user_procedures,字段是id、procedure(注意这是MySQL关键字,必须用反引号包裹)、date,用聚合函数+CASE语句就能解决:
SELECT id, -- 替换编码并生成对应项目列和日期列 MAX(CASE WHEN `procedure` = 2 THEN '常规体检' ELSE NULL END) AS 常规体检项目, MAX(CASE WHEN `procedure` = 2 THEN `date` ELSE NULL END) AS 常规体检日期, MAX(CASE WHEN `procedure` = 3 THEN '血液检测' ELSE NULL END) AS 血液检测项目, MAX(CASE WHEN `procedure` = 3 THEN `date` ELSE NULL END) AS 血液检测日期, MAX(CASE WHEN `procedure` = 4 THEN '影像扫描' ELSE NULL END) AS 影像扫描项目, MAX(CASE WHEN `procedure` = 4 THEN `date` ELSE NULL END) AS 影像扫描日期, MAX(CASE WHEN `procedure` = 5 THEN '心电图' ELSE NULL END) AS 心电图项目, MAX(CASE WHEN `procedure` = 5 THEN `date` ELSE NULL END) AS 心电图日期, MAX(CASE WHEN `procedure` = 8 THEN '术后复查' ELSE NULL END) AS 术后复查项目, MAX(CASE WHEN `procedure` = 8 THEN `date` ELSE NULL END) AS 术后复查日期 FROM user_procedures WHERE id = 12345 GROUP BY id;
场景2:同一编码存在多条重复记录(比如多次做同一项检查)
如果同一个ID下,同一个procedure编码有多个日期记录,需要先给每条同编码的记录按日期排序编号,再转列:
-- 先给同编码的记录按日期排序编号 WITH ranked_procs AS ( SELECT id, `procedure`, `date`, ROW_NUMBER() OVER (PARTITION BY id, `procedure` ORDER BY `date`) AS rn FROM user_procedures WHERE id = 12345 ) SELECT id, -- 按编号生成多组项目+日期列 MAX(CASE WHEN `procedure` = 2 AND rn = 1 THEN '常规体检' ELSE NULL END) AS 常规体检1项目, MAX(CASE WHEN `procedure` = 2 AND rn = 1 THEN `date` ELSE NULL END) AS 常规体检1日期, MAX(CASE WHEN `procedure` = 2 AND rn = 2 THEN '常规体检' ELSE NULL END) AS 常规体检2项目, MAX(CASE WHEN `procedure` = 2 AND rn = 2 THEN `date` ELSE NULL END) AS 常规体检2日期, -- 其他编码同理扩展 MAX(CASE WHEN `procedure` = 3 AND rn = 1 THEN '血液检测' ELSE NULL END) AS 血液检测1项目, MAX(CASE WHEN `procedure` = 3 AND rn = 1 THEN `date` ELSE NULL END) AS 血液检测1日期 FROM ranked_procs GROUP BY id;
之前出错的核心原因
你之前的写法没加MAX()/MIN()这类聚合函数,GROUP BY之后,CASE语句只会返回分组内第一行符合条件的值,其他行的结果会被直接忽略,导致大部分列显示NULL,日期也只取到第一行数据。加上聚合函数后,会把分组内所有行中符合CASE条件的非NULL值提取出来,正好对应每个编码的目标记录。
内容的提问来源于stack exchange,提问作者user21220560
相关产品推荐
相关产品推荐

