在日常工作中,经常遇到需要将行转列的情况。通过近段时间的学习,分别将几种实现方式总结如下:
一、DECODE 方式
SELECT
CASE WHEN GROUPING(A.SSSWJG_ID)=1 THEN '151170000' ELSE A.SSSWJG_ID END SWJG_DM,
SUM(DECODE(A.SZ_ID,'10101',A.SJJE)) ZZS,
SUM(DECODE(A.SZ_ID,'10102',A.SJJE)) XFS,
SUM(DECODE(A.SZ_ID,'10104',A.SJJE)) QYSDS,
SUM(DECODE(A.SZ_ID,'10106',A.SJJE)) QYSDS,
SUM(DECODE(A.SZ_ID,'10107',A.SJJE)) ZYS
FROM
(
select T.SSSWJG_ID,T.SZ_ID, sum(T.RKSE) SJJE
from tab1_jks t JOIN tab3_sz R ON t.sz_id=r.sz_id
where TO_CHAR(T.RKJZRQ, 'YYYYMM') = '202002'
AND R.SJSZ_ID='10100'
group by T.SSSWJG_ID,T.SZ_ID
)A
GROUP BY ROLLUP(A.SSSWJG_ID);
使用时,需要结合group by进行分组汇总,否则会有数据溢出效应。
二、CASE WHEN 方式
SELECT
CASE WHEN GROUPING(A.SSSWJG_ID)=1 THEN '151170000' ELSE A.SSSWJG_ID END JG_DM,
SUM(CASE WHEN A.SZ_ID='10101' THEN A.RKSE ELSE 0 END) ZZS,
SUM(CASE WHEN A.SZ_ID='10102' THEN A.RKSE ELSE 0 END) XFS,
SUM(CASE WHEN A.SZ_ID='10104' THEN A.RKSE ELSE 0 END) QYSDS,
SUM(CASE WHEN A.SZ_ID='10106' THEN A.RKSE ELSE 0 END) GRSDS,
SUM(CASE WHEN A.SZ_ID='10107' THEN A.RKSE ELSE 0 END) ZYS
FROM
(
select T.SSSWJG_ID,T.SZ_ID, sum(T.RKSE) RKSE
from tab1_jks t JOIN tab3_sz R ON T.SZ_ID=R.SZ_ID
where TO_CHAR(T.RKJZRQ, 'YYYYMM') = '202002'
AND R.SJSZ_ID='10100'
group by T.SSSWJG_ID,T.SZ_ID
)A
GROUP BY ROLLUP(A.SSSWJG_ID);
使用时,需要结合group by进行分组汇总,否则会有数据溢出。
三、PIVOT方式
SELECT *
FROM (select T.SSSWJG_ID SSSWJG_ID, T.SZ_ID, sum(t.RKSE) sjje
from tab1_jks t
join tab3_sz a
on a.sz_id = t.sz_id
where TO_CHAR(T.RKJZRQ,'YYYYMM')='202002'
AND a.SJSZ_ID = '10100'
group by t.SSSWJG_ID, t.SZ_ID) O --1.对zs_jks表按税务机关和征收项目进行分组汇总。
PIVOT(SUM(O.SJJE) FOR SZ_ID IN('10101' zzs,
'10102' xfs,
'10104' qysds,
'10106' grsds,
'10107' zys,
'10109' cjs,
'10110' fcs,
'10111' yhs,
'10112' cztdsys,
'10113' tdzzs,
'10114' ccs,
'10116' clgzs,
'10118' gzs,
'10119' qs,
'10121' hbs));
pivot(col_name1 for col_name2 in() )子句中,col_name1是原表中需要转置后作为新表中列数据的字段;col_name2是原表中需要在新表中作为列标题的字段;in子句中应包含col_name2在原表中去除重复值后的数据集合。
四、不使用pivot
SELECT TEST1.ID, TEST1.SZ_ID, TEST2.SZ_ID, TEST3.SZ_ID
FROM (SELECT T.SSSWJG_ID ID, SUM(T.RKSE) SZ_ID
FROM TAB1_JKS T
JOIN TAB3_SZ A
ON A.SZ_ID = T.SZ_ID
WHERE TO_CHAR(T.RKJZRQ, 'YYYYMM') = '202002'
AND A.SJSZ_ID = '10100'
AND A.SZ_ID = '10101'
GROUP BY T.SSSWJG_ID, T.SZ_ID) TEST1
LEFT JOIN (SELECT T.SSSWJG_ID ID, SUM(T.RKSE) SZ_ID
FROM TAB1_JKS T
JOIN TAB3_SZ A
ON A.SZ_ID = T.SZ_ID
WHERE TO_CHAR(T.RKJZRQ, 'YYYYMM') = '202002'
AND A.SJSZ_ID = '10100'
AND A.SZ_ID = '10102'
GROUP BY T.SSSWJG_ID, T.SZ_ID) TEST2
ON TEST1.ID = TEST2.ID
LEFT JOIN (SELECT T.SSSWJG_ID ID, SUM(T.RKSE) SZ_ID
FROM TAB1_JKS T
JOIN TAB3_SZ A
ON A.SZ_ID = T.SZ_ID
WHERE TO_CHAR(T.RKJZRQ, 'YYYYMM') = '202002'
AND A.SJSZ_ID = '10100'
AND A.SZ_ID = '10104'
GROUP BY T.SSSWJG_ID, T.SZ_ID) TEST3
ON TEST2.ID = TEST3.ID
LEFT JOIN (SELECT T.SSSWJG_ID ID, SUM(T.RKSE) SZ_ID
FROM TAB1_JKS T
JOIN TAB3_SZ A
ON A.SZ_ID = T.SZ_ID
WHERE TO_CHAR(T.RKJZRQ, 'YYYYMM') = '202002'
AND A.SJSZ_ID = '10100'
AND A.SZ_ID = '10106'
GROUP BY T.SSSWJG_ID, T.SZ_ID) TEST4
ON TEST3.ID = TEST4.ID
LEFT JOIN (SELECT T.SSSWJG_ID ID, SUM(T.RKSE) SZ_ID
FROM TAB1_JKS T
JOIN TAB3_SZ A
ON A.SZ_ID = T.SZ_ID
WHERE TO_CHAR(T.RKJZRQ, 'YYYYMM') = '202002'
AND A.SJSZ_ID = '10100'
AND A.SZ_ID = '10107'
GROUP BY T.SSSWJG_ID, T.SZ_ID) TEST5
ON TEST4.ID = TEST5.ID
五、与tab5_swjg连接,格式化输出结果。
SELECT Y.JGMC,
X.ZZS,
X.XFS,
X.QYSDS,
X.GRSDS,
X.ZYS,
X.CJS,
X.FCS,
X.YHS,
X.CZTDSYS,
X.TDZZS,
X.CCS,
X.CLGZS,
X.GZS,
X.QS,
X.HBS
FROM (SELECT CASE
WHEN GROUPING(Q.ID) = 1 THEN
'15117000000'
ELSE
Q.ID
END ID,
SUM(Q.ZZS) ZZS,
SUM(Q.XFS) XFS,
SUM(Q.QYSDS) QYSDS,
SUM(Q.GRSDS) GRSDS,
SUM(Q.ZYS) ZYS,
SUM(Q.CJS) CJS,
SUM(Q.FCS) FCS,
SUM(Q.YHS) YHS,
SUM(Q.CZTDSYS) CZTDSYS,
SUM(Q.TDZZS) TDZZS,
SUM(Q.CCS) CCS,
SUM(Q.CLGZS) CLGZS,
SUM(Q.GZS) GZS,
SUM(Q.QS) QS,
SUM(Q.HBS) HBS
FROM (
SELECT *
FROM (SELECT T.SSSWJG_ID ID, T.SZ_ID, SUM(T.RKSE) SJJE
FROM TAB1_JKS T
JOIN TAB3_SZ A
ON A.SZ_ID = T.SZ_ID
WHERE TO_CHAR(T.RKJZRQ, 'YYYYMM') = '202002'
AND A.SJSZ_ID = '10100'
GROUP BY T.SSSWJG_ID, T.SZ_ID) O --1.对tab_jks表按机构id和sZ_id进行分组汇总。
PIVOT(SUM(O.SJJE)
FOR SZ_ID IN('10101' ZZS,
'10102' XFS,
'10104' QYSDS,
'10106' GRSDS,
'10107' ZYS,
'10109' CJS,
'10110' FCS,
'10111' YHS,
'10112' CZTDSYS,
'10113' TDZZS,
'10114' CCS,
'10116' CLGZS,
'10118' GZS,
'10119' QS,
'10121' HBS))) Q
GROUP BY ROLLUP(Q.ID)) X
JOIN (SELECT R.SWJG_ID ID,
LPAD(' ', (LEVEL - 1) * 4) || R.SWJG_NAME JGMC,
LEVEL LEVEL_ID,
ROWNUM RN
FROM TAB4_SWJG R
START WITH R.SWJG_ID = '15117000000'
CONNECT BY PRIOR R.SWJG_ID = SJSWJG_ID) Y
ON X.ID = Y.ID
ORDER BY Y.RN