SQL 行列转换之 CASE WHEN 和UNION ALL 的用法
Posted Vics异地我就
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL 行列转换之 CASE WHEN 和UNION ALL 的用法相关的知识,希望对你有一定的参考价值。
SQL 行列转换之 CASE WHEN 和UNION ALL 的用法
建表语句部门表
CREATE TABLE DEPT(
DEPTNO INT PRIMARY KEY, -- 部门编号
DNAME VARCHAR(14) , -- 部门名称
LOC VARCHAR(13) -- 部门地址
) ;
-- 部门数据:
INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON');
员工表
CREATE TABLE EMP
(
EMPNO INT PRIMARY KEY, -- 员工编号
ENAME VARCHAR(10), -- 员工名称
JOB VARCHAR(9), -- 工作
MGR DOUBLE, -- 直属领导编号
HIREDATE DATE, -- 入职时间
SAL DOUBLE, -- 工资
COMM DOUBLE, -- 奖金
DEPTNO INT, -- 部门号
FOREIGN KEY(DEPTNO) REFERENCES DEPT(DEPTNO)
);
INSERT INTO EMP VALUES
(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO EMP VALUES
(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO EMP VALUES
(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO EMP VALUES
(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO EMP VALUES
(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO EMP VALUES
(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO EMP VALUES
(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO EMP VALUES
(7788,'SCOTT','ANALYST',7566,'1987-07-13',3000,NULL,20);
INSERT INTO EMP VALUES
(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO EMP VALUES
(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO EMP VALUES
(7876,'ADAMS','CLERK',7788,'1987-07-13',1100,NULL,20);
INSERT INTO EMP VALUES
(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO EMP VALUES
(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
INSERT INTO EMP VALUES
(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);
行转列
原表样子
建表语句
select DEPTNO, count(EMPNO) cnt from emp group by DEPTNO;
利用case when 语句进行列转行
select max(case when DEPTNO = '10' then cnt else null end) deptno_10
, max(case when DEPTNO = '20' then cnt else null end) deptno_20
, max(case when DEPTNO = '30' then cnt else null end) deptno_30
from (select DEPTNO, count(EMPNO) cnt from emp group by DEPTNO) t1;
代码说明 select 字段1...字段N 就会产生N 个列,因此3行就使用3个字段来对应。
利用case when 将deotno 中的对应数值,then 成 cnt 里面的数值。 直接使用then +列名 会将同行的数值直接赋值过去
其他非deptno =10 的数值 用else null 赋值, 方便后面整理统计。
select (case when DEPTNO = '10' then cnt else null end) deptno_10
, (case when DEPTNO = '20' then cnt else null end) deptno_20
, (case when DEPTNO = '30' then cnt else null end) deptno_30
from (select DEPTNO, count(EMPNO) cnt from emp group by DEPTNO) t1;
最后利用max 或者sum 函数进行去重即可,
使用union 进行行转列
建表语句
CREATE TABLE DEPT2(
DEPTNO_10 INT PRIMARY KEY,
DEPTNO_20 INT ,
DEPTNO_30 INT);
INSERT INTO DEPT2 VALUES (3,5,6)
行转列语句
select '10' as DEPTNO, DEPTNO_10 from dept2
union
select '20' as DEPTNO, DEPTNO_20 from dept2
union
select '30' as DEPTNO, DEPTNO_30 from dept2
语句说明
利用select 增加第一列 列名为DEPTNO , 列的内容全部为10
再选择所有dept2 中列名为 DEPTNO_10 以下的内容
(如果DEPTNP_10 有N行 就会产生N行的数字10 即 DEPTNO 名下的10 会随着DEPTNO_10的内容增加而增加)
如图我手动将DEPTNP_10增加为2行,观察DEPTNO 的列变化
利用union或者union all 进行链接
以上是关于SQL 行列转换之 CASE WHEN 和UNION ALL 的用法的主要内容,如果未能解决你的问题,请参考以下文章