zoukankan      html  css  js  c++  java
  • 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;
       

     

  • 相关阅读:
    手机网页中 唤醒拨打电话和发送短信,浏览器和微信浏览器都可以用
    用于滚动 焦点图的MSClass
    oracle使用connect by进行级联查询 树型菜单
    Jstl标签汇总
    EL表达式报错:  According to TLD or attribute directive in tag file, attribute value does not accept any expressions
    EL表达式简介
    SSM整合(四)-整合后配置文件汇总
    Maven的pom报maven-surefire-plugin:pom:2.12.4
    SSM整合(三):Spring4与Mybatis3与SpringMVC整合
    SSM整合(二):Spring4与Mybatis3整合
  • 原文地址:https://www.cnblogs.com/Jims2016/p/5728137.html
Copyright © 2011-2022 走看看