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.1.4 判断鼠标点击DataGridView的第几行还是空白处
public int GetRowIndexAt(int mouseLocation_Y) { if (dvaw.FirstDisplayedScrollingRowIndex < 0) { r ...
- Java中弱引用、软引用、虚引用及强引用的区别
Java中弱引用VS软引用 Java中有如下四种类型的引用: 强引用(Strong Reference) 弱引用(WeakReference) 软引用(SoftReference) 虚引用(Phant ...
- k8s cookbook读书笔记 第二章
走一遍概念 An overview of Kubernetes control f Working with pods f Working with a replication controller ...
- eclipse安卓模拟器Failed to install on device 'emulator-5554': timeout处理方案
我们在用模拟器调试的时候,经常会出现Failed to install on device 'emulator-5554': timeout这个错误.其实就是有些虚拟器在部署的时候时间过于长.系统就认 ...
- python的面向对象编程
面向对象编程是一种程序的范式,它把程序看成是对不同对象的相互调用,对现实世界建立的一种模型. 面向对象编程的基本思想,类和实例.类用于定义抽象对象,实例根据类的定义被创建出来. 在python当中我们 ...
- with上下文管理基础
import queue import contextlib import time @contextlib.contextmanager def worker_state(xxx,val): xxx ...
- iOS 通过接受距离传感器的消息改变屏幕的明暗度(仅限用于真实的手机)
#import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL ...
- SDUT 3404 数据结构实验之排序七:选课名单.!?
数据结构实验之排序七:选课名单 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 随着学校规模 ...
- Java分层概念(转)
Java分层概念(转) 对于分层的概念,似乎之间简单的三层,多了,就有点难以区分了,所以收藏了这个. ervice是业务层 action层即作为控制器 DAO (Data Access Object) ...
- delphi xe6 让 ListView 在 Android 可回弹[根据龟山阿卍原创修改为xe6版本]
Delphi XE6 找出 FMX.Platform.Android.pas 档案,并复制到自己的 Project 路径里,找到 GetScrollingBehaviour 函数,修改成如下: uni ...