有如下三张表:

销售表: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','','上海','A',1000);
INSERT INTO SALE_FACT VALUES('C00001','','上海','B',5000);
INSERT INTO SALE_FACT VALUES('C00001','','上海','C',300);
INSERT INTO SALE_FACT VALUES('C00001','','上海','D',800);
INSERT INTO SALE_FACT VALUES('C00004','','北京','E',600);
INSERT INTO SALE_FACT VALUES('C00004','','长春','F',300);
INSERT INTO SALE_FACT VALUES('C00006','','沈阳','G',9000);
INSERT INTO SALE_FACT VALUES('C00007','','哈尔滨','H',800);
INSERT INTO SALE_FACT VALUES('C00008','','沈阳','I',2200);
INSERT INTO SALE_FACT VALUES('C00008','','大连','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','','A',5);
INSERT INTO VISIT_FACT VALUES('C00001','','B',6);
INSERT INTO VISIT_FACT VALUES('C00001','','C',9);
INSERT INTO VISIT_FACT VALUES('C00001','','D',22);
INSERT INTO VISIT_FACT VALUES('C00004','','E',33);
INSERT INTO VISIT_FACT VALUES('C00004','','F',44);
INSERT INTO VISIT_FACT VALUES('C00006','','G',100);
INSERT INTO VISIT_FACT VALUES('C00007','','H',6);
INSERT INTO VISIT_FACT VALUES('C00008','','I',9);
INSERT INTO VISIT_FACT VALUES('C00008','','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;

Oracle练习(2)的更多相关文章

  1. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  2. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 5.安装Database软件 5. ...

  3. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 1.实施前准备工作 1.1 服务器安装操 ...

  4. Oracle 的基本操作符

    != 不等于 select empno,ename,job from scott.emp where job!='manager' ^= 不等于 select empno,ename,job from ...

  5. 使用Zabbix监控Oracle数据库

    Orabbix介绍 监控Oracle数据库我们需要安装第三方提供的Zabbix插件,我们先测试比较有名的Orabbix,http://www.smartmarmot.com/product/orabb ...

  6. 基于Oracle安装Zabbix

    软件版本 Oracle Enterprise Linux 7.1 64bit Oracle Enterprise Edition 12.1.0.2 64bit Zabbix 3.2.1 准备工作 上传 ...

  7. Oracle Database 12c Data Redaction介绍

    什么是Data Redaction Data Redaction是Oracle Database 12c的高级安全选项之中的一个新功能,Oracle中国在介绍这个功能的时候,翻译为“数据编纂”,在EM ...

  8. 使用Oracle官方巡检工具ORAchk巡检数据库

    ORAchk概述 ORAchk是Oracle官方出品的Oracle产品健康检查工具,可以从MOS(My Oracle Support)网站上下载,免费使用.这个工具可以检查Oracle数据库,Gold ...

  9. 利用Oracle RUEI+EM12c进行应用的“端到端”性能诊断

    概述 我们知道,影响一个B/S应用性能的因素,粗略地说,有以下几个大的环节: 1. 客户端环节 2. 网络环节(可能包括WAN和LAN) 3. 应用及中间层环节 4. 数据库层环节 能够对各个环节的问 ...

  10. 使用技术手段限制DBA的危险操作—Oracle Database Vault

    概述 众所周知,在业务高峰期,某些针对Oracle数据库的操作具有很高的风险,比如修改表结构.修改实例参数等等,如果没有充分评估和了解这些操作所带来的影响,这些操作很可能会导致故障,轻则导致应用错误, ...

随机推荐

  1. Java-API-Package:org.springframework.stereotype

    ylbtech-Java-API-Package:org.springframework.stereotype 1.返回顶部 1. @NonNullApi @NonNullFields Package ...

  2. HTTP-Runoob:HTTP简介

    ylbtech-HTTP-Runoob:HTTP简介 1.返回顶部 1. HTTP 简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网 ...

  3. AWS + Stunnel + Squid ***

    [需求] 第一,能***. 第二,在企业网络要能突破端口限制. [原理] 利用AWS提供的一年免费EC2服务,搭建一台自己的VPS,在VPS中利用Stunnel与本机建立加密连接,将本地http请求通 ...

  4. 3D柜体导出CAD优化参考方案

    前言: 近期在做系统柜和衣柜导出CAD的工作,现阶段的工作是根据不同的厂商定制不同的CAD导出,其中房间平面图.顶脚线截面图.柜体立面图.侧视图.平面图.门板图等模块功能都基本固定,不同的是不同厂商的 ...

  5. 2011-03-17免Oracle客户端连远程Oracle的方法

    1.http://www.oracle.com/technetwork/topics/winsoft-085727.html上下载对应版本的instanctclinet zip包 34M 解压后92M ...

  6. CentOS 7.2 部署Rsync + Lsyncd服务实现文件实时同步/备份 (一)

    接收端配置: 1.安装rsync yum -y install rsync 2.配置同步模块 1. 编辑同步配置文件 vi /etc/rsyncd.conf 2. 同步模块配置参数 # any nam ...

  7. Linux 对mysql远程授权连接操作 和 查看mysql数据库和表 基本命令

    Linux 对mysql远程连接的授权操作 首先linux连接mysql数据库 授权: grant all on *.* to ' with grant option; //允许账户root从任何主机 ...

  8. leetcode443

    使用两个数组分别记录字符和对应的数字,然后清除原来的vector,重新向里面添加元素.注意判断1个字符时,不将'1'加入vector. int compress(vector<char>& ...

  9. lombok与spring的恩怨

    下面是lombok按照 Java Bean 的规范生成的 下面是spring mvc里jackson 需要的 xXxx问题还是顺势而为吧

  10. hibernate学习笔记(5)在数据库中存取图片

    如何从数据库读取存入的图片,即Blob(二进制)数据. 先从数据库读取对象. 再从获取的对象中得到blob对象. 通过blob对象的getBinaryStream()方法获取input输出流. 之后通 ...