Oracle行转列语法总结

备注:测试以Oracle 11g下的scoot schema为例

需求:求emp表各个岗位的工资之和,如无,用0代替

如需要scott用户下建表及录入数据语句,可参考:
scott建表及录入数据sql脚本

一.decode语法

SELECT deptno,
       nvl(SUM(decode(job, 'MANAGER', sal)), 0) s_MANAGER,
       nvl(SUM(decode(job, 'ANALYST', sal)), 0) s_ANALYST,
       nvl(SUM(decode(job, 'CLERK', sal)), 0) s_CLERK,
       nvl(SUM(decode(job, 'PRESIDENT', sal)), 0) s_PRESIDENT,
       nvl(SUM(decode(job, 'SALESMAN', sal)), 0) s_SALESMAN
  FROM emp
 GROUP BY deptno;

在这里插入图片描述

二.CASE语法

SELECT deptno,
       nvl(sum(case when job = 'MANAGER' then sal else 0 end),0)  s_MANAGER,
       nvl(sum(case when job = 'ANALYST' then sal else 0 end),0)  s_ANALYST,
       nvl(sum(case when job = 'CLERK' then sal else 0 end),0)    s_CLERK,
       nvl(sum(case when job = 'PRESIDENT' then sal else 0 end),0)  s_PRESIDENT,
       nvl(sum(case when job = 'SALESMAN' then sal else 0 end),0)  s_SALESMAN
  FROM emp
 GROUP BY deptno;

在这里插入图片描述

三.PIVOT语法

WITH p AS
 (SELECT deptno, job, sal FROM emp)
SELECT *
  FROM p pivot(SUM(sal) FOR job IN('MANAGER' AS s_MANAGER,
                                   'ANALYST' AS s_ANALYST,
                                   'CLERK' AS s_CLERK,
                                   'PRESIDENT' AS s_PRESIDENT,
                                   'SALESMAN' AS s_SALESMAN));

在这里插入图片描述
不过这个地方null值没有替换成0,要通过nvl再转换一下

WITH p AS
 (SELECT deptno, job, sal FROM emp),
tmp AS
 (SELECT *
    FROM p pivot(SUM(sal) FOR job IN('MANAGER' AS s_MANAGER,
                                     'ANALYST' AS s_ANALYST,
                                     'CLERK' AS s_CLERK,
                                     'PRESIDENT' AS s_PRESIDENT,
                                     'SALESMAN' AS s_SALESMAN)))
SELECT deptno,
       nvl(s_MANAGER, 0) s_MANAGER,
       nvl(s_ANALYST, 0) s_ANALYST,
       nvl(s_CLERK, 0) s_CLERK,
       nvl(s_PRESIDENT, 0) s_PRESIDENT,
       nvl(s_SALESMAN, 0) s_SALESMAN
  FROM tmp

在这里插入图片描述

小结:

decode 语法简单,Oracle独有
case sql标准语法
pivot 语法最为简单,Oracle、sqlserver、postgresql均可以使用

下面再来讲讲wm_concat、listagg、xmlagg
需求:部门编号为20的所有的员工信息,以行的形式显示

四.wm_contact语法

SELECT T.DEPTNO, wm_concat(t.ename) names
  FROM EMP T
 WHERE T.DEPTNO = '20'
 GROUP BY T.DEPTNO;

在这里插入图片描述
在这里插入图片描述

五.listagg语法

SELECT T.DEPTNO,
       listagg(T.ENAME, ',') WITHIN GROUP(ORDER BY T .ENAME) names
  FROM EMP T
 WHERE T.DEPTNO = '20'
 GROUP BY T.DEPTNO;

在这里插入图片描述

六.xmlagg语法

SELECT T.DEPTNO,
       xmlagg(XMLELEMENT(T, ',',T.ENAME) ORDER BY T .ENAME).EXTRACT ('//text()') names
  FROM EMP T
 WHERE T.DEPTNO = '20'
 GROUP BY T.DEPTNO;

在这里插入图片描述

在这里插入图片描述

小结:

wm_concat 语法最简单,但是默认是 clob列,plsql不容易导出
listtagg 语法稍微复杂,但是默认是字符串,性能会比wm_concat 好,但是超过4000个字符,受限制。
xmlagg 字符串超过4000字符,就需要使用xmlagg

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
引用\[1\]提供了一些SQL语句的优化技巧,包括避免使用*、减少数据库的访问次数、删除重复记录、多使用commit、使用where替换having、多使用内部函数提高sql语句效率、多使用表的别名、使用exists替换in、使用not exists替换not in、尽量使用索引类进行查询、避免在索引列上进行计算、避免在索引类上使用not、可以使用>=替换>、使用in替换or、尽量使用where替换group by、避免使用消耗资源的操作如union等。引用\[2\]提供了Oracle中常见的数据类型,包括varchar2、char和varchar。引用\[3\]提供了一个带两个变量的语句的示例。 综合以上引用内容,Oracle语法大全包括SQL语句的优化技巧和常见的数据类型。在编写SQL语句时,可以根据引用\[1\]中的优化技巧来提高查询效率,避免不必要的资源消耗。同时,需要了解Oracle中常见的数据类型,如varchar2、char和varchar,以便正确定义和使用表的字段。此外,还可以参考引用\[3\]中的示例来学习如何使用变量进行查询。 #### 引用[.reference_title] - *1* *2* [ORACLE基础常见语法汇总](https://blog.csdn.net/weixin_44628049/article/details/94844513)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Oracle 50个常用语法](https://blog.csdn.net/qq_34156628/article/details/90741743)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值