Oracle练习(2)

有如下三张表:

销售表:SALE_FACT

 工号   年月   城市   客户   销售额 
C00001 201601 上海 A 1000
C00001 201601 上海 B 5000
C00001 201601 上海 C 300
C00001 201601 上海 D 800
C00004 201601 北京 E 600
C00004 201602 长春 F 300
C00006 201603 沈阳 G 9000
C00007 201604 哈尔滨 H 800
C00008 201605 沈阳 I 2200
C00008 201606 大连 J 1200

 

 

 

 

 

 

 

 

 

 

员工表:DIM_EMP

工号 姓名
C00001 张三
C00002 李四
C00003 王五
C00004 赵六
C00005 林七
C00006 钱八
C00007 宋十
C00008 李白
C00009 陆游
C00010 王林

 

 

 

 

 

 

 

 

 

 

拜访表:VISIT_FACT

工号 年月 客户 拜访次数
C00001 201601 A 5
C00001 201601 B 6
C00001 201601 C 9
C00001 201601 D 22
C00004 201601 E 33
C00004 201602 F 44
C00006 201603 G 100
C00007 201604 H 6
C00008 201605 I 9
C00008 201606 J 8

 

 

 

 

 

 

 

 

 

问题如下:

1.查出每个员工每个月的总销售额

2.查出每个员工每个月的总拜访次数

3.查出每个员工每个城市的总销售额

4.查出全年销售额最大的员工

5.列出全年销售额从大到小排序员工姓名及其全年销售额

6.列出每个员工当年的销售额及其当年总的拜访次数

7.查出拜访次数最多的员工的全年销售额

下面我们先进行前期表和数据的准备

1.创建销售事实表:

CREATE TABLE SALE_FACT(
     EMPNO NVARCHAR2(10)
    ,YEAR_MONTH CHAR(6)
    ,CITY VARCHAR(10)
    ,CLIENT VARCHAR(10)
    ,SALES NUMBER);

 2.往销售事实表中插入数据:

--往销售事实表中插入数据
INSERT INTO SALE_FACT VALUES('C00001','201601','上海','A',1000);
INSERT INTO SALE_FACT VALUES('C00001','201601','上海','B',5000);
INSERT INTO SALE_FACT VALUES('C00001','201601','上海','C',300);
INSERT INTO SALE_FACT VALUES('C00001','201601','上海','D',800);
INSERT INTO SALE_FACT VALUES('C00004','201601','北京','E',600);
INSERT INTO SALE_FACT VALUES('C00004','201602','长春','F',300);
INSERT INTO SALE_FACT VALUES('C00006','201603','沈阳','G',9000);
INSERT INTO SALE_FACT VALUES('C00007','201604','哈尔滨','H',800);
INSERT INTO SALE_FACT VALUES('C00008','201605','沈阳','I',2200);
INSERT INTO SALE_FACT VALUES('C00008','201606','大连','J',1200);

3.创建员工维度表:

CREATE TABLE DIM_EMP(
  EMPNO NVARCHAR2(10)
 ,EMPNAME NVARCHAR2(10));

4.往员工维度表插入数据:

--往员工维度表插入数据
INSERT INTO DIM_EMP VALUES('C00001','张三'); 
INSERT INTO DIM_EMP VALUES('C00002','李四');
INSERT INTO DIM_EMP VALUES('C00003','王五');
INSERT INTO DIM_EMP VALUES('C00004','赵六');
INSERT INTO DIM_EMP VALUES('C00005','林七');
INSERT INTO DIM_EMP VALUES('C00006','钱八');
INSERT INTO DIM_EMP VALUES('C00007','宋十');
INSERT INTO DIM_EMP VALUES('C00008','李白');
INSERT INTO DIM_EMP VALUES('C00009','陆游');
INSERT INTO DIM_EMP VALUES('C00010','王林');

5.创建员工拜访事实表:

CREATE TABLE VISIT_FACT(
  EMPNO NVARCHAR2(10)
 ,YEAR_MONTH CHAR(6)
 ,CLIENT NVARCHAR2(10)
 ,VISIT_COUNT NUMBER);

6.往拜访事实表插入数据:

--往拜访事实表插入数据
INSERT INTO VISIT_FACT VALUES('C00001','201601','A',5);
INSERT INTO VISIT_FACT VALUES('C00001','201601','B',6);
INSERT INTO VISIT_FACT VALUES('C00001','201601','C',9);
INSERT INTO VISIT_FACT VALUES('C00001','201601','D',22);
INSERT INTO VISIT_FACT VALUES('C00004','201601','E',33);
INSERT INTO VISIT_FACT VALUES('C00004','201602','F',44);
INSERT INTO VISIT_FACT VALUES('C00006','201603','G',100);
INSERT INTO VISIT_FACT VALUES('C00007','201604','H',6);
INSERT INTO VISIT_FACT VALUES('C00008','201605','I',9);
INSERT INTO VISIT_FACT VALUES('C00008','201606','J',8);
  • 查出每个员工每个月的总销售额

          这里特别注意,每个员工,每个月,想想一共会有几条数据??比如说有10个员工,一年12个月,求每个员工每个月的总销售额,会有几条数据呢?

当然是10*12=120条了,而这里我们考虑1至6月,而销售事实表中有些员工根本没有销售数据(如:C00002  、C00003  等),也有些员工不是每个月都有销售数据(如:C00001只有1月有销售数据,其他月份没有销售数据),换句话说,就是:数据不全,不能保证每个员工每个月都有销售额,所以为了查出的数据完整,我们需要补全这些数据并且没有就按0来算。

     首先我们要做的是把所有员工都拉到销售表中来,对应的就是和员工表join,同时对每个员工相同月份的销售额进行求和,对应代码如下:

     

SELECT
  t2.empname
 ,t1.year_month
 ,SUM(NVL(t1.sales,0)) 
 FROM SALE_FACT t1 
 RIGHT JOIN DIM_EMP t2
 ON t1.empno=t2.empno
 GROUP BY  t2.empnamE ,t1.year_month
 ORDER BY 1;

  这里所有员工都被拉进来了,并且李白和赵六有两个月的销售额,其他人只有一个月或者一个月也没有

然后再对每个员工每个月进行补充数据,我们先要选出所有的日期,这里我们从销售表中选出日期,一般情况下各个公司会有一个日期维度表,这里我们

用distinct选出year_month,对应代码:

SELECT DISTINCT e.year_month FROM SALE_FACT e  ORDER BY 1

接下来的重点是怎么让每个人有每个月的总销售额呢?这里主要用到了partition by方法,

好了,前期日期表和所有员工部分月的总销售额表都准备好了,开始吧:

WITH all_emp_part_date AS(
     SELECT
     t2.empname
     ,t1.year_month
     ,SUM(NVL(t1.sales,0)) sumsal 
     FROM SALE_FACT t1 
     RIGHT JOIN DIM_EMP t2
     ON t1.empno=t2.empno
     GROUP BY  t2.empnamE ,t1.year_month
     ORDER BY 1),
    temp_date AS(
     SELECT  DISTINCT e.year_month FROM SALE_FACT e  ORDER BY 1)  
   SELECT
      t1.empname
     ,t2.year_month
     ,NVL(t1.sumsal,0) as mounthSales
    FROM all_emp_part_date t1
   partition by (t1.empname)   --对日期进行稠化
   right join temp_date t2
   on t1.year_month=t2.year_month;

注意:这里的重点是对数据实现补充,或者说稠化数据吧,详细方法可以看看数据稠化

最终的结果,一共是60条:

 好了,这样每个员工,每个月的总销售额以及可以完整的显示了,那么

每个员工,每个城市,每个月的总销售额呢?  

你肯定知道的是:返回结果数=员工数*城市数*月数

每个员工,每个城市,每个客户,每个月的总销售额呢?

相信你,能行的!!!

 好了,下一个题目,查出每个员工每个月的总拜访次数,是不是和第一题差不多呢?

直接来代码吧:

 --2.查出每个员工每个月的总拜访次数
WITH all_emp_part_date AS(
     SELECT
      t2.empname
     ,t1.year_month
     ,SUM(NVL(t1.visit_count,0)) sumvis 
     FROM VISIT_FACT t1 
     RIGHT JOIN DIM_EMP t2
     ON t1.empno=t2.empno
     GROUP BY  t2.empname ,t1.year_month
     ORDER BY 1),
    temp_date AS(
     SELECT  DISTINCT e.year_month FROM SALE_FACT e  ORDER BY 1)  
   SELECT
      t1.empname
     ,t2.year_month
     ,NVL(t1.sumvis,0) as mounthVisit
    FROM all_emp_part_date t1
   partition by (t1.empname)
   right join temp_date t2
   on t1.year_month=t2.year_month;

第三题,查出每个员工每个城市的总销售额,依旧如此,把月份替换城市,代码如下:

--查出每个员工每个城市的总销售额
WITH all_emp_part_city AS(
     SELECT
     t2.empname
     ,t1.city
     ,SUM(NVL(t1.sales,0)) sumsal 
     FROM SALE_FACT t1 
     RIGHT JOIN DIM_EMP t2
     ON t1.empno=t2.empno
     GROUP BY  t2.empname,t1.city
     ORDER BY 1),
     temp_city AS(
          SELECT DISTINCT t1.city FROM SALE_FACT t1)
     SELECT 
       t1.empname
      ,t2.city
      ,NVL(t1.sumsal,0)
      FROM all_emp_part_city t1 
     PARTITION BY (t1.empname)
     RIGHT JOIN temp_city t2
     ON t1.city=t2.city;

第四题:查出全年销售额最大的员工

这里是查出全年销售额,先sum一下,在求出最大的值以及员工

 WITH RANK_SAL AS
   ( SELECT t2.empname,NVL(SUM(t1.sales),0) as sumsal FROM SALE_FACT t1 
    right join  DIM_EMP t2 
    ON t1.empno=t2.empno
    GROUP BY t2.empname)
    SELECT * FROM RANK_SAL t1 WHERE t1.sumsal = (select max(t1.sumsal) from RANK_SAL t1);

第五题:列出全年销售额从大到小排序员工姓名及其全年销售额

--5.列出全年销售额从大到小排序员工姓名及其全年销售额
 SELECT t2.empname,NVL(SUM(t1.sales),0) sumsal FROM SALE_FACT t1 
    right join  DIM_EMP t2 
    ON t1.empno=t2.empno
    GROUP BY t2.empname order by sumsal desc;

 带排名

SELECT 
     t2.empname
     ,NVL(SUM(t1.sales),0) as sumsal
     ,dense_rank() over(order by NVL(SUM(t1.sales),0) desc )
     FROM SALE_FACT t1 
    right join  DIM_EMP t2 
    ON t1.empno=t2.empno
    GROUP BY t2.empname;

 第六题:列出每个员工当年的销售额及其当年总的拜访次数

 

 WITH SALACCOUNT AS
  (SELECT  
    t1.empname
   ,t1.empno
   ,sum(t2.sales) salsum
   FROM DIM_EMP t1 
   LEFT JOIN SALE_FACT t2
   on t1.empno=t2.empno
   group by t1.empname,t1.empno)
   SELECT t1.empname,nvl(t1.salsum,0) , nvl(sum(t2.visit_count),0)  FROM  SALACCOUNT t1 
   left join VISIT_FACT t2 
   on t2.empno=t1.empno group by t1.empname,t1.salsum;
   

 

 

posted @ 2016-08-02 09:46  Blue眼泪2016  阅读(191)  评论(0编辑  收藏  举报