select deptno,case when deptno=10then'第一部门' when deptno=20then'第二部门' when deptno=30then'第三部门' else'第四部门' endfrom emp;
case when 生成的列也可以丢到 group by 后面去分组的,where、having都可以 使用case表达式需注意的点: 各个分支<表达式>返回的数据类型要统一 case写完后不能丢了end else可省略但不建议省,没有值时可写 else null case when 是一个列,可以起别名,可以放在group by后
decode 等值翻译
1 2
-- 把10号部门翻译成“十号部门”,20号部门翻译成“二十号部门”,30号部门翻译成“三十号部门”,其他显示其他部门,翻译时可以对列进行处理 select decode(deptno,10,'十号部门',20,'二十号部门',30,'三十号部门','其他部门') from emp
decode与case when 的比较: 1、decode 只有Oracle、informix才有,其它数据库不支持; 2、case when的用法, Oracle、SQL Server、 MySQL、 informix、都支持; 3、decode 只能用做相等判断,但是可以配合sign函数进行大于,小于,等于的判断,CASE when可用于=,>=,<,<=,<>,is null,is not null 等的判断; 4、decode 使用其来比较简洁,CASE 虽然复杂但更为灵活; 5、另外,在decode中,null和null是相等的,但在case when中,只能用is null来判断。 6、decode效率比case when高,Oracle环境中能用decode尽量不用case when
行转列
聚合case实现行转列
1 2 3 4 5 6 7 8
-- 求各部门的各职位的工资 -- 各职位('SALESMAN'、'MANAGER'、'CLERK')作为列名 -- 空格后的 salesman、manager、clerk是别名 select deptno, max(casewhen job='SALESMAN'then sal end) salesman, max(casewhen job='MANAGER'then sal end) manager, max(casewhen job='CLERK'then sal end) clerk from emp groupby deptno
pivot 行转列
1 2 3 4 5 6 7 8 9 10 11
-- 格式 select*from (数据查询集) --后面行转列用到的字段 pivot( (行转列后列的值) for 需要转的列 in (转换后的列值) ) -- 求各部门的各职位的工资 select*from (select deptno,job,sal from emp) pivot ( max(sal) for job in ('SALESMAN','MANAGER','CLERK') ) -- 行转列后的值应是聚集函数集
selectsum(sal) from emp selectsum(sal),deptno from emp groupby deptno selectsum(sal)over() from emp
selectsum(sal)over(partitionby deptno) from emp --累计效果的partition by 有需要则加,没需要就不加 select deptno,sal,sum(sal)over(orderby sal) from emp
--partition by 可以和group by 共存,前提是group by分组后的列,才能做的排序(可以用但是很少用到) select deptno,row_number()over(partitionby deptno orderby deptno desc) r from emp groupby deptno
listagg 将多行合并成一行
1 2 3 4 5 6 7 8 9 10 11 12 13
--作为普通函数,对工资进行排序,用顿号'、'进行拼接。 selectlistagg(ename,'、')withingroup(orderby sal) name from emp; --作为分组函数: select deptno,listagg(ename,'、')withingroup(orderby sal) name from emp groupby deptno; --作为分析函数: select deptno,ename,sal,listagg(ename,'、')withingroup(orderby sal)over(partitionby deptno)name from emp;
-- 1.把10号部门翻译成“十号部门”,20号部门翻译成“二十号部门”,30号部门翻译成“三十号部门” select deptno, case deptno when10then'十号部门' when20then'二十号部门' when30then'三十号部门' else'其他部门' end 部门 from emp -- 2.给所有的10号部门员工加薪10% 20号部门的员工加薪20% 30号员工加薪30% ,其他部门加薪5% select ename,deptno,sal,case when deptno=10then sal*1.1 when deptno=20then sal*1.2 when deptno=30then sal*1.3 else sal*1.05 end new_sal from emp
-- 3.统计工资级别相应的数量(1600以下 C级,1600-3000 B级,3000以上 A级) --方法1 selectcase when sal<1600then'C级' when sal between1600and3000then'B级' when sal>3000then'A级' elsenull end 工资级别, count(1) 合计 from emp groupbycase when sal<1600then'C级' when sal between1600and3000then'B级' when sal>3000then'A级' elsenull end --方法2 select count(casewhen sal<1600then'C级'end) C级, count(casewhen sal between1600and3000then'B级'end) B级, count(casewhen sal>3000then'A级'end) A级 from emp
-- 4.实现两种方法的行转列 -- 聚合case select deptno, max(casewhen job='SALESMAN'then sal end) salesman, max(casewhen job='MANAGER'then sal end) manager, max(casewhen job='CLERK'then sal end) clerk from emp groupby deptno
-- pivot select*from (select deptno,job,sal from emp) pivot ( max(sal) for job in ('SALESMAN','MANAGER','CLERK') )
--1.按照部门编号升序查找所有部门名称,用、隔开 selectlistagg(dname,'、') withingroup(orderby deptno) from dept
--2.按照工资降序查找每个部门的员工姓名,用、隔开 select deptno,listagg(ename,'、') withingroup(orderby sal desc) from emp groupby deptno orderby deptno