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

Oracle SQL实现hist表多列转行(禁用CONNECT BY语法)

解决方案:将宽表多列转为行数据(无CONNECT BY)

好的,咱们来搞定这个需求——把hist表里的多组workN/salN列拆成每行对应一组的格式,而且不用CONNECT BY,这里有两个完全可行的方案:

方案1:使用UNION ALL(兼容所有Oracle版本)

这个方法兼容性拉满,不管你用的是哪个版本的Oracle都能跑通。核心思路就是把每组workN和salN分别作为单独的查询,再用UNION ALL把结果合并起来。

示例SQL代码:

SELECT emi_id, work1 AS work, sal1 AS sal FROM hist
UNION ALL
SELECT emi_id, work2 AS work, sal2 AS sal FROM hist
UNION ALL
SELECT emi_id, work3 AS work, sal3 AS sal FROM hist
...
UNION ALL
SELECT emi_id, work15 AS work, sal15 AS sal FROM hist
ORDER BY emi_id, sal; -- 可选:按需求排序

注意:要把上面的...替换成从work4/sal4到work14/sal14的对应查询语句,确保15组都覆盖到。如果某些行的workN/salN为空,UNION ALL会保留这些行;如果想过滤空值,可以在每个子查询里加WHERE workN IS NOT NULL AND salN IS NOT NULL。

方案2:使用UNPIVOT(Oracle 11g及以上版本适用)

如果你的Oracle版本是11g或更高,用UNPIVOT会更简洁,代码量少很多,可读性也更强。这个语法专门用来处理宽表转长表的场景,而且可以同时处理成对的列(比如work和sal是一组)。

示例SQL代码:

SELECT emi_id, work, sal
FROM hist
UNPIVOT (
    (work, sal) FOR work_sal_pair IN (
        (work1, sal1) AS 'job_1',
        (work2, sal2) AS 'job_2',
        (work3, sal3) AS 'job_3',
        ...
        (work15, sal15) AS 'job_15'
    )
)
ORDER BY emi_id; -- 可选:按需求排序

这里的work_sal_pair是一个临时的列名,用来标识每组数据的来源(比如job_1对应第一组),你可以根据自己的习惯修改。同样,如果要过滤空值,可以在UNPIVOT后面加WHERE work IS NOT NULL AND sal IS NOT NULL。

两个方案都完全符合你的要求,不需要用到CONNECT BY语法,你可以根据自己的Oracle版本选择最合适的那个。

内容的提问来源于stack exchange,提问作者Tamil Mani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:59:22