= Pivoting a Result Set into Multiple Rows
mysql> select job, ename from EMP order by job; +-----------+--------+ | job | ename | +-----------+--------+ | ANALYST | SCOTT | | ANALYST | FORD | | CLERK | JAMES | | CLERK | ADAMS | | CLERK | SMITH | | CLERK | MILLER | | MANAGER | BLAKE | | MANAGER | CLARK | | MANAGER | JONES | | PRESIDENT | KING | | SALESMAN | MARTIN | | SALESMAN | TURNER | | SALESMAN | WARD | | SALESMAN | ALLEN | +-----------+--------+ 14 rows in set (0.00 sec)
== Solution: MySQL
You would like to format the result set such that each job gets its own column:
mysql> select max(case when job ='clerk' then ename else null end) as clerks,
-> max(case when job ='analyst' then ename else null end) as analysts,
-> max(case when job ='manager' then ename else null end) as managers,
-> max(case when job ='president' then ename else null end) as presidents,
-> max(case when job ='salesman' then ename else null end) as salesmen
-> from ( select e.job, e.ename,
-> (select count(*) from EMP d
-> where e.job = d.job and e.empno < d.empno) as rnk
-> from EMP e
-> ) x
-> group by rnk;
+--------+----------+----------+------------+----------+
| clerks | analysts | managers | presidents | salesmen |
+--------+----------+----------+------------+----------+
| MILLER | FORD | CLARK | KING | TURNER |
| JAMES | SCOTT | BLAKE | NULL | MARTIN |
| ADAMS | NULL | JONES | NULL | WARD |
| SMITH | NULL | NULL | NULL | ALLEN |
+--------+----------+----------+------------+----------+
4 rows in set (0.00 sec)
mysql> select deptno, max(case when job ='clerk' then ename else null end) as clerks,
-> max(case when job ='analyst' then ename else null end) as analysts,
-> max(case when job ='manager' then ename else null end) as managers,
-> max(case when job ='president' then ename else null end) as presidents,
-> max(case when job ='salesman' then ename else null end) as salesmen
-> from ( select e.deptno, e.job, e.ename,
-> (select count(*) from EMP d
-> where e.job = d.job and e.empno < d.empno) as rnk
-> from EMP e
-> ) x
-> group by deptno, rnk;
+--------+--------+----------+----------+------------+----------+
| deptno | clerks | analysts | managers | presidents | salesmen |
+--------+--------+----------+----------+------------+----------+
| 10 | MILLER | NULL | CLARK | KING | NULL |
| 20 | NULL | FORD | NULL | NULL | NULL |
| 20 | NULL | SCOTT | NULL | NULL | NULL |
| 20 | ADAMS | NULL | JONES | NULL | NULL |
| 20 | SMITH | NULL | NULL | NULL | NULL |
| 30 | NULL | NULL | NULL | NULL | TURNER |
| 30 | JAMES | NULL | BLAKE | NULL | MARTIN |
| 30 | NULL | NULL | NULL | NULL | WARD |
| 30 | NULL | NULL | NULL | NULL | ALLEN |
+--------+--------+----------+----------+------------+----------+
9 rows in set (0.00 sec)
== Solution: Oracle, SQL Server
select max(case when job ='clerk' then ename else null end) as clerks,
max(case when job ='analyst' then ename else null end) as analysts,
max(case when job ='manager' then ename else null end) as managers,
max(case when job ='president' then ename else null end) as presidents,
max(case when job ='salesman' then ename else null end) as salesmen
from ( select job, ename,
row_number() over(partition by job order by ename) rn
from EMP
) x
group by rn;