原始表如下:
第1題,12.2變換結(jié)果集成多行
例:你想把行變換成列敛瓷,需要的結(jié)果不止一行学赛,你希望返回每個員工和他們的職位
(此類題型與日歷生成類似年堆,日歷可以format自動生成用來group by的列,此處只能自己生成盏浇,該題還與下方第6題類似)
需要最終結(jié)果:
答:
#步驟1:生成rnk列变丧,最最關(guān)鍵
create table x as
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
order by 1,3
#步驟2:形成要求的格式
select max(case when job='CLERK' then ename end) as CLERK,
max(case when job='ANALYST' then ename end) as ANALYSTS,
max(case when job='MANAGER' then ename end) as MGRS,
max(case when job='PRESIDENT' then ename end) as PREZ,
max(case when job='SALESMAN' then ename end) as SALES
from x
group by rnk
(精髓是rnk的形成)
步驟1結(jié)果:
第2題,12.3反向轉(zhuǎn)換結(jié)果集(列變成行)
例:想把列數(shù)據(jù)變?yōu)樾袛?shù)據(jù)绢掰,分兩步
需要最終結(jié)果:
第一步結(jié)果:
第二步結(jié)果:
答:
#步驟1:
create table x as
select sum(case when deptno=10 then 1 else 0 end) as deptno_10,
sum(case when deptno=20 then 1 else 0 end) as deptno_20,
sum(case when deptno=30 then 1 else 0 end) as deptno_30
from emp
#步驟2:
select dept.deptno, case when deptno=10 then x.deptno_10
when deptno=20 then x.deptno_20
when deptno=30 then x.deptno_30
end as count_by_dept
from x, (select distinct deptno from dept where deptno<=30 order by 1) dept
第3題痒蓬,12.7創(chuàng)建固定大小的數(shù)據(jù)桶
例:你希望基于EMPNO值為EMP表里的員工分組,一組最多5人(桶的數(shù)量不限制滴劲,但每個桶最多裝5個數(shù)據(jù))
需要最終結(jié)果:
答:
select ceil(rnk/5) as grp, empno ename
from (select e.empno, e.ename, (select count(*) from emp d where e.empno < d.empno)+1 as rnk
from emp e) x
order by grp
(此處count(*) 必須從0開始攻晒,否則要用floor(rnk/5)要出問題的)
第4題,12.8創(chuàng)建預(yù)定數(shù)目的桶
例:你希望把EMP表中的員工分別放入到4個桶里面(桶的數(shù)量一定班挖,里面裝多少數(shù)據(jù)可變)
需要最終結(jié)果:
答:
select mod(count(*),4)+1 as grp, e.empno, e.ename
from emp e, emp d
where e.empno>=d.empno
group by e.empno, e.ename
order by 1
第5題鲁捏,12.9創(chuàng)建水平直方圖
例:希望以水平直方圖的形式顯示每個部門的員工人數(shù),用'*'代表一個員工
需要最終結(jié)果:
答:
select deptno, lpad('',count(*),'*') as cnt
from emp
group by deptno
第6題萧芙,12.10創(chuàng)建垂直直方圖
例:希望以垂直直方圖的形式顯示每個部門的員工人數(shù)给梅,用'*'代表一個員工
需要最終結(jié)果:
答:
#步驟1:形成rnk列,最最關(guān)鍵
create table x as
select case when e.deptno=10 then '*' end deptno_10,
case when e.deptno=20 then '*' end deptno_20,
case when e.deptno=30 then '*' end deptno_30,
(select count(*) from emp d where e.deptno=d.deptno and e.empno<d.empno) as rnk
from emp e
order by 4,3,2,1
#步驟2:按照要求的格式排列
select max(deptno_10) as d10,
max(deptno_20) as d20,
max(deptno_30) as d30
from x
group by rnk
order by 1 ,2 ,3
(最后的排序双揪,可能不同的數(shù)據(jù)庫不一樣动羽,可以升序降序都試一下,按照自己的喜好來)
步驟1結(jié)果:
第7題渔期,12.11返回非分組列
例:希望找出每個部門工資最高和最低的員工运吓,同時也找出每個職位對應(yīng)的工資最高和最低的員工
需要最終結(jié)果:
答:
#步驟1:
create table y as
select e.deptno, e.ename, e.job, e.sal,
(select max(sal) from emp d where d.deptno = e.deptno) as maxdept,
(select max(sal) from emp d where d.job = e.job) as maxjob,
(select min(sal) from emp d where d.deptno = e.deptno) as mindept,
(select min(sal) from emp d where d.job = e.job) as minjob
from emp e
#步驟2:
select deptno, ename, job, sal,
case when sal=maxdept then 'top_sal_in_dept'
when sal=mindept then 'low_sal_in_dept'
end as dept_status,
case when sal=maxjob then 'top_sal_in_job'
when sal=minjob then 'low_sal_in_job'
end as dept_status
from y
where sal in (maxdept,mindept,maxjob,minjob)
order by 1
步驟1結(jié)果:
第8題,12.12計算簡單的小計
例:希望得到一個結(jié)果集疯趟,既包含了EMP表各個JOB對應(yīng)的工資合計值拘哨,也包括全部工資的總計
需要最終結(jié)果:
答:
select coalesce(job,'total') job, sum(sal) sal
from emp
group by job with rollup
第9題,12.17按照時間單位分組
例:你有一些交易日志迅办,希望每隔5秒?yún)R總一下這些數(shù)據(jù)
生成交易日制表trx_log1:
create table trx_log (TRX_ID int,
TRX_DATE DATETIME(6),
TRX_CNT INT)
insert into trx_log values (1,'2005-07-28 19:03:07',44),
(2,'2005-07-28 19:03:08',18),
(3,'2005-07-28 19:03:09',23),
(4,'2005-07-28 19:03:10',29),
(5,'2005-07-28 19:03:11',27),
(6,'2005-07-28 19:03:12',45),
(7,'2005-07-28 19:03:13',45),
(8,'2005-07-28 19:03:14',32),
(9,'2005-07-28 19:03:15',41),
(10,'2005-07-28 19:03:16',15),
(11,'2005-07-28 19:03:17',24),
(12,'2005-07-28 19:03:18',47),
(13,'2005-07-28 19:03:19',37),
(14,'2005-07-28 19:03:20',48),
(15,'2005-07-28 19:03:21',46),
(16,'2005-07-28 19:03:22',44),
(17,'2005-07-28 19:03:23',36),
(18,'2005-07-28 19:03:24',41),
(19,'2005-07-28 19:03:25',33),
(20,'2005-07-28 19:03:26',19)
create trx_log1 as
select TRX_ID, date_format(TRX_DATE,'%d-%b-%Y %T') as TRX_DATE ,TRX_CNT
from trx_log
交易日制表trx_log1如下圖所示:
需要最終結(jié)果:
答:
select ceil(trx_id/5)as grp,
min(trx_date) as trx_start,
max(trx_date) as trx_end,
sum(trx_cnt) as total
from trx_log1
group by ceil(trx_id/5)
第10題宅静,12.18多維度聚合運算
例:希望得到一個結(jié)果集章蚣,包括每個員工的姓名站欺、部門、他所在部門的員工總數(shù)(包括他自己)纤垂、和他做相同工作的員工總數(shù)(包括他自己)矾策,以及EMP表中的員工總?cè)藬?shù)
需要最終結(jié)果:
答:
select e.ename,
e.deptno,
(select count(*) from emp d where d.deptno=e.deptno) as deptno_cnt,
job,
(select count(*) from emp d where d.job=e.job) as job_cnt,
(select count(*) from emp ) as total
from emp e
第11題,12.9動態(tài)區(qū)間聚合運算
例:希望把入職最早的員工的hiredate作為起點峭沦,每隔90天計算一次工資合計值贾虽。想調(diào)查一下,在最早入職的員工和最近入職的員工之間每隔90天工資的波動狀況
需要最終結(jié)果:
答:
select e.hiredate, e.sal,
(select sum(sal) from emp d
where d.hiredate between e.hiredate-90 and e.hiredate) as spending_pattern
from emp e
order by 1