You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SQL将多列员工ID与姓名转为垂直输出(Unpivot实现)

解决多组EmpId/EmpName列转垂直格式的问题

嘿,我来帮你搞定这个麻烦的格式转换问题!先明确下你的场景:表里面有Cid,还有整整50组配对的EmpIdN和EmpNameN列,你不想写50次UNION ALL折腾自己,已经尝试用UNPIVOT处理ID列,现在想把对应的姓名列也一起转成目标的垂直格式。

最简洁的解决方案:用CROSS APPLY(SQL Server)或LATERAL JOIN(PostgreSQL/MySQL 8.0+)

这种方法可以一次性处理所有配对的ID和姓名列,不用重复写冗余逻辑,完美适配你有50组列的场景。

以你的示例表为例,对应的查询代码如下:

SELECT 
    emp_label,
    emp_value
FROM emp
CROSS APPLY (
    VALUES
        ('Emp1', CAST(EmpId1 AS VARCHAR(50))),
        ('EmpName1', EmpName1),
        ('Emp2', CAST(EmpId2 AS VARCHAR(50))),
        ('EmpName2', EmpName2),
        -- 按照这个格式继续添加,直到Emp50和EmpName50
        ('Emp50', CAST(EmpId50 AS VARCHAR(50))),
        ('EmpName50', EmpName50)
) AS unpivoted_data(emp_label, emp_value)
WHERE cid = 1;

代码逻辑解释

  1. CROSS APPLY + VALUES组合:相当于在每行数据内部,把50组EmpIdN/EmpNameN拆分成100行(每组对应两行:ID行和姓名行),VALUES子句里的每一行就是你想要的垂直格式的一条记录。
  2. 类型统一处理:因为EmpId是数值类型,EmpName是字符串类型,所以需要把EmpId转成字符串(比如CAST(xxx AS VARCHAR(50))),保证输出的emp_value列类型一致,避免报错。
  3. 扩展性极强:你只需要照着('EmpN', CAST(EmpIdN AS VARCHAR(50))), ('EmpNameN', EmpNameN)的格式,把50组都补进VALUES里就行,比写50次UNION ALL清爽太多。

如果坚持想用UNPIVOT怎么处理?

要是你更习惯用UNPIVOT,可以先把ID和姓名分别做unpivot,再通过标签的编号关联起来:

WITH id_unpivot AS (
    SELECT 
        REPLACE(ids, 'Emp', '') AS emp_num,
        CAST(id AS VARCHAR(50)) AS emp_value,
        'Emp' + REPLACE(ids, 'Emp', '') AS emp_label
    FROM (
        SELECT EmpId1 AS Emp1, EmpId2 AS Emp2, ..., EmpId50 AS Emp50
        FROM emp WHERE cid = 1
    ) AS upvt
    UNPIVOT (
        id FOR ids IN (Emp1, Emp2, ..., Emp50)
    ) AS upvt
),
name_unpivot AS (
    SELECT 
        REPLACE(names, 'EmpName', '') AS emp_num,
        name AS emp_value,
        'EmpName' + REPLACE(names, 'EmpName', '') AS emp_label
    FROM (
        SELECT EmpName1 AS EmpName1, EmpName2 AS EmpName2, ..., EmpName50 AS EmpName50
        FROM emp WHERE cid = 1
    ) AS upvt
    UNPIVOT (
        name FOR names IN (EmpName1, EmpName2, ..., EmpName50)
    ) AS upvt
)
SELECT emp_label, emp_value
FROM id_unpivot
UNION ALL
SELECT emp_label, emp_value
FROM name_unpivot
ORDER BY emp_num;

不过这种方法需要写两次unpivot,还要处理标签的编号关联,不如CROSS APPLY直观简洁,更推荐第一种方案。


内容的提问来源于stack exchange,提问作者Jen K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:35:13