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','','上海','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)的更多相关文章
- Oracle分析函数入门
一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...
- 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. ...
- 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 服务器安装操 ...
- Oracle 的基本操作符
!= 不等于 select empno,ename,job from scott.emp where job!='manager' ^= 不等于 select empno,ename,job from ...
- 使用Zabbix监控Oracle数据库
Orabbix介绍 监控Oracle数据库我们需要安装第三方提供的Zabbix插件,我们先测试比较有名的Orabbix,http://www.smartmarmot.com/product/orabb ...
- 基于Oracle安装Zabbix
软件版本 Oracle Enterprise Linux 7.1 64bit Oracle Enterprise Edition 12.1.0.2 64bit Zabbix 3.2.1 准备工作 上传 ...
- Oracle Database 12c Data Redaction介绍
什么是Data Redaction Data Redaction是Oracle Database 12c的高级安全选项之中的一个新功能,Oracle中国在介绍这个功能的时候,翻译为“数据编纂”,在EM ...
- 使用Oracle官方巡检工具ORAchk巡检数据库
ORAchk概述 ORAchk是Oracle官方出品的Oracle产品健康检查工具,可以从MOS(My Oracle Support)网站上下载,免费使用.这个工具可以检查Oracle数据库,Gold ...
- 利用Oracle RUEI+EM12c进行应用的“端到端”性能诊断
概述 我们知道,影响一个B/S应用性能的因素,粗略地说,有以下几个大的环节: 1. 客户端环节 2. 网络环节(可能包括WAN和LAN) 3. 应用及中间层环节 4. 数据库层环节 能够对各个环节的问 ...
- 使用技术手段限制DBA的危险操作—Oracle Database Vault
概述 众所周知,在业务高峰期,某些针对Oracle数据库的操作具有很高的风险,比如修改表结构.修改实例参数等等,如果没有充分评估和了解这些操作所带来的影响,这些操作很可能会导致故障,轻则导致应用错误, ...
随机推荐
- 2015 浙江省赛 Beauty of Array (思维题)
Beauty of Array Edward has an array A with N integers. He defines the beauty of an array as the summ ...
- 查看osdmap命令
标签(空格分隔): ceph,ceph运维,osdmap 方法一: 最直接,简单的命令: [root@node3 ~]# ceph osd tree ID CLASS WEIGHT TYPE NAME ...
- java ----获取路径的各种方法(总结)
Java Web开发中路径问题小结 (1) Web开发中路径的几个基本概念 假设在浏览器中访问了如下的页面,如图1所示: 那么针对这个站点的几个基本概念表述如下: 1. web站点的根目录:http: ...
- fontconfig
vlc-android 默认是 禁用 fontconfig 的 如果想要使用的话需要手动修改 compile.sh
- 封装 Toast
一. ToastView.java 1 import android.content.Context; import android.view.LayoutInflater; import andro ...
- [转]PHP部分常见算法
1. 用户密码六位数,不能大于六位而不能小于六数,数字值正则为[0-9],请用PHP写出有几种可能性,并做暴力破解; function dePassword($pwd) { $tmp = array( ...
- MySQL数据库规范
Mysql数据库规范 一.基础规范 [强制]使用InnoDB存储引擎解读:InnoDB存储引擎是MySQL默认存储引擎,支持事务和行级锁,并发性能更好,CPU及内存缓存页优化使得资源利用率更高[强制] ...
- 初步认识ASP.NET WebForm
C#可已进行以下两大类的开发 一.客户端应用程序C/S 主要有两种开发技术: 1.winForm windows窗体应用程序 2.WPF微软新一代图形框架 MFC(比较老的开发技术) MVVM(客户端 ...
- String/StringBuilder 类 用对象数组实现登录注册功能
一.需求说明:实现用户注册.登陆功能: 程序中使用一个长度为3的对象数组,存储用户的登录名和密码: 例如如下格式: 登录名 密码 生日 爱好 zhangsan 11 ...
- 面试题:3年工作经验 已看1 有用 memcache和redis有什么区别
此内容偏中高级,适合有三年经验者. 1. java中wait和sleep有什么区别?多线程条件下如何保证数据安全? 答:最大区别是等待时wait会释放锁(乐观锁),而sleep会一直持有锁 ...