MySQL报表和数据仓库[11题]

原始表如下:


emp

dept

第1题,12.2变换结果集成多行

例:你想把行变换成列,需要的结果不止一行,你希望返回每个员工和他们的职位
(此类题型与日历生成类似,日历可以format自动生成用来group by的列,此处只能自己生成,该题还与下方第6题类似)

需要最终结果:

答:

#步骤1:生成rnk列,最最关键
create table x as
select e.job, e.ename, (select count(*) from emp d 
                         where e.job=d.job and e.empno

(精髓是rnk的形成)
步骤1结果:


步骤1

第2题,12.3反向转换结果集(列变成行)

例:想把列数据变为行数据,分两步

需要最终结果:
第一步结果:

第二步结果:


答:

#步骤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创建固定大小的数据桶

例:你希望基于EMPNO值为EMP表里的员工分组,一组最多5人(桶的数量不限制,但每个桶最多装5个数据)

需要最终结果:

答:

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创建预定数目的桶

例:你希望把EMP表中的员工分别放入到4个桶里面(桶的数量一定,里面装多少数据可变)

需要最终结果:

答:

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创建水平直方图

例:希望以水平直方图的形式显示每个部门的员工人数,用'*'代表一个员工

需要最终结果:

答:

select deptno, lpad('',count(*),'*') as cnt
from emp
group by deptno

第6题,12.10创建垂直直方图

例:希望以垂直直方图的形式显示每个部门的员工人数,用'*'代表一个员工

需要最终结果:

答:

#步骤1:形成rnk列,最最关键
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

(最后的排序,可能不同的数据库不一样,可以升序降序都试一下,按照自己的喜好来)

步骤1结果:


步骤1

第7题,12.11返回非分组列

例:希望找出每个部门工资最高和最低的员工,同时也找出每个职位对应的工资最高和最低的员工

需要最终结果:

答:

#步骤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结果:


步骤1

第8题,12.12计算简单的小计

例:希望得到一个结果集,既包含了EMP表各个JOB对应的工资合计值,也包括全部工资的总计

需要最终结果:

答:

select coalesce(job,'total') job, sum(sal) sal
from emp
group by job with rollup

第9题,12.17按照时间单位分组

例:你有一些交易日志,希望每隔5秒汇总一下这些数据

生成交易日制表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如下图所示:


需要最终结果:

答:

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多维度聚合运算

例:希望得到一个结果集,包括每个员工的姓名、部门、他所在部门的员工总数(包括他自己)、和他做相同工作的员工总数(包括他自己),以及EMP表中的员工总人数

需要最终结果:

答:

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动态区间聚合运算

例:希望把入职最早的员工的hiredate作为起点,每隔90天计算一次工资合计值。想调查一下,在最早入职的员工和最近入职的员工之间每隔90天工资的波动状况

需要最终结果:

答:

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

你可能感兴趣的:(MySQL报表和数据仓库[11题])