有如下三张表:

销售表: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. 学习vue

    一,声明模板的时候需要新建示例 如下代码 <div id="app"> <my></my> </div> Vue.component ...

  2. Eclipse中的普通Java项目如何部署到Tomcat中

    我现在的做法: 1.在Eclipse中配置Tomcat时,选择创建Context文件,而不是server.xml,好处是文件可以随便命名,与虚拟目录一致(即xml中的属性path).Tomcat加载项 ...

  3. Redis的持久化机制

    持久化机制 RDB:快照模式AOF :日志模式 多数据库– 一个redis服务器内部默认有16个数据,编号О0-15– 默认操作是编号为0的数据库– 可以在命令行用select选择数据库127.0.0 ...

  4. mycat 分片

    1  配置下面两种ER分片,并结合日志分析子表插入过程中的不同 (1).父表按照主键ID分片,子表的分片字段与主表ID关联,配置为ER分片 (2).父表的分片字段为其他字段,子表的分片字段与主表ID关 ...

  5. [置顶] getenv、setenv函数(获取和设置系统环境变量) 与 环境变量

    1.getenv() 函数名: getenv 功 能: 从环境中取字符串,获取环境变量的值 头文件: stdlib.h 用 法:char *getenv(char *envvar); 函数说明:get ...

  6. pthread_cond_wait 详解

    转自:http://www.xuebuyuan.com/2173853.html pthread_cond_wait() 用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或 ...

  7. [Python]python CGI脚本在apache服务器上运行时出现“Premature end of script headers”错误

    在测试自己的python CGI脚本时, 当html网页中的表单form内容传送到服务器python脚本时, 总是出现Premature end of script headers错误, 网页显示是服 ...

  8. C语言学习笔记--动态库和静态库的使用

    1.C语言中的链接器 (1)每个 C 语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件. (2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正 ...

  9. TCP/IP 笔记 1.2 链 路 层

    都是包含三种类型.根据类型字段的值来进行区分 2.4 SLIP:串行线路IPS L I P的全称是Serial Line IP.它是一种在串行线路上对 I P数据报进行封装的简单形式,在RFC 105 ...

  10. 洛谷P3328(bzoj 4085)毒瘤线段树

    题面及大致思路:https://www.cnblogs.com/Yangrui-Blog/p/9623294.html, https://www.cnblogs.com/New-Godess/p/45 ...