Oracle学习日记——使用数字 oracle数据库number
lipiwang 2024-10-18 09:38 10 浏览 0 评论
1.使用聚集函数
select deptno,
min(sal) as 最小值,
max(sal) as 最大值,
sum(sal) as 工资合计,
count(sal) as 计数,
avg(sal) as 错误平均值,
avg(coalesce(sal,0)) as 正确平均值
from emp group by deptno
正确平均值和错误平均值的意义:
聚集函数会忽略空值,对sum不会造成影响,但是对avg,connt会造成影响,所以根据需求决定是否需要把空值转换为0
注意:当表中没有数据时,不加group by会返回一条数据,加了group by没有数据返回。
验证过程:
建立空表:create table emp2 as select * from emp where 1 = 2
select count(*) from emp2 group by deptno
没有group by :0
有group by:空值
所以在实际使用过程中要注意group by 的位置
2.生成累计和
案例:公司为了查看用人成本,需要对员工的工资进行累加,以便查看员工人数和工资支出之间对应的关系
首先,按照进入公司的先后顺序进行查看:
select empno,empname,sal,sum(sal) over(order by empno) from emp where deptno = '2' order by empno
用listagg()来查看每个值具体是由哪些值相加
select
empno,
empname,
sal,
sum(sal) over(order by empno),
(select listagg(sal,'+') within group(order by empno)
from emp b
where b.deptno = '2'
and b.empno <= a.empno) 计算公式
from emp a
where deptno = '2' order by empno
3.计算累计差
创建项目费用表
create table detail as
select 1000 as 编号,'预交费用' as 项目,30000 as 金额 from dual;
insert into detail
select empno as 编号,'支出' || rownum as 项目,sal+1000 as 金额
from emp where deptno = '2'
detail表中的内容为消费流水账
需求:得到每笔消费的余额
需求分析:
(1)一般流水账的编号都是按照顺序生成的,所以根据编号来排序并生成序号
select rownum as seq,a.* from (select 编号,项目,金额 from detail order by 编号 desc) a
(2)观察查询结果 seq = 1 的为收入,后面的为支出,可以用case when把后面的数据变为负数
with x as
(select rownum as seq,a.* from (select 编号,项目,金额 from detail order by 编号 desc) a )
select 编号,项目,金额,(case when seq = 1 then 金额 else -金额 end) as 转换后的值 from x;
(3)把转换后的结果进行相加,可以得到差值
with x as
(select rownum as seq,a.* from (select 编号,项目,金额 from detail order by 编号 desc) a )
select 编号,项目,金额,sum(case when seq = 1 then 金额 else -金额 end) over(order by seq) as 余额 from x;
4.更改累计和的值
创建测试视图
create or replace view v(id,amt,trx)
as
select 1,100,'PR' FROM DUAL UNION ALL
select 2,300,'PR' FROM DUAL UNION ALL
select 3,150,'PY' FROM DUAL UNION ALL
select 4,50,'PY' FROM DUAL UNION ALL
select 5,200,'PY' FROM DUAL UNION ALL
select 6,100,'PR' FROM DUAL UNION ALL
select 7,300,'PY' FROM DUAL UNION ALL
select 8,400,'PR' FROM DUAL ;
这是一个存取款列表:
id是唯一值
amt表示每次存取款涉及的金额
trx列定义了事务处理的类型,取款是"PY",存款是"PR"。
(1)把取款值变为负数
select id,
case when trx = 'PY' THEN '取款' else '存款' end 存取类型,
amt 金额,
case when trx = 'PY' THEN AMT ELSE -amt end 变更后的值
from v order by id
(2)把变更后的值进行相加
select id,
case when trx = 'PY' then '取款' else '存款' end 存取类型,
amt 金额,
sum(case when trx = 'PY' THEN AMT ELSE -AMT END) over(order by id) 余额
from v
order by id;
5.返回各部门工资排名前三位的员工
select deptno,
empno,
sal,
row_number() over(partition by deptno order by sal desc) as row_number,
rank() over(partition by deptno order by sal desc) as rank,
dense_rank() over(partition by deptno order by sal desc) as dense_rank
from emp
where deptno in (2,3)
order by 1,3 desc;
partition by:会把主查询返回的子句分组进行分析。观察查询结果,对子句进行部门分组以后,部门为2的生成序列以后,部门为3的部门生成序列时,会重新进行分组。
当工资有重复项时,观察row_number,rank,dense_rank的区别
row_number:仍然会生成序号1、2、3
rank:相同的工资会生成相同的序号,而且其后的序号与row_number相同,即1,1,3,3,5
dense_rank:相同的工资会生成相同的序号,其后的序号会递增,即1,1,2,3,3,4
6.计算出现次数最多的值:
案例要求:查看部门中哪个工资等级的员工最多
(1)计算不同工资出现的次数
select sal,count(*) as 出现次数 from emp where deptno = 2 group by sal order by sal
(2)按次数排序生成序号
select sal,dense_rank() over(order by 出现次数 desc) as 次数排序
from (select sal,count(*) as 出现次数 from emp where deptno = 2 group by sal)x;
(3)根据序号过滤得到需要的结果
select sal
from (select sal,dense_rank() over(order by 出现次数 desc)as 次数排序 from (select sal,count(*) as 出现次数 from emp where deptno = 2 group by sal)x)y
where 次数排序 = 1
(4)利用partition by子句分别查询各部门哪个工资等级的员工最多
select deptno,sal
from (select deptno, sal,dense_rank() over(partition by deptno order by 出现次数 desc)as 次数排序
from (select sal,deptno,count(*) as 出现次数 from emp group by sal,deptno)x)y
where 次数排序 = 1
7.返回最值所在行数据
方案1:
标量查询:先取出最大值,再和最大值进行关联,思路简单,sql复杂
select
a.empname as 工资最高的人,a.deptno,a.sal,a.max_sal
from (
select max(sal) over(partition by deptno) as max_sal,empno,sal,empname,deptno from emp) a
where sal = a.max_sal
方案2:
分析函数:在Oracle里有分析函数可以直接满足这个需求,而且还可以方便的同时取最大值和最小值
select
deptno,
empno,
max(empname) keep(dense_rank first order by sal) over(partition by deptno) as 工资最低的人,
max(empname) keep(dense_rank last order by sal) over(partition by deptno) as 工资最高的人,
empname,
sal
from emp
order by 1,6 desc
first、last语句也可以放在group里与其他聚合函数一样使用,这是要去掉后面的over(partition by xxx)
select
deptno,
min(sal) as min_sal,
max(empname) keep(dense_rank first order by sal) as 工资最低的人,
max(sal) as max_sal,
max(empname) keep(dense_rank last order by sal) as 工资最高的人
from emp
group by deptno
在第一个分析函数的语句中,不论是first,还是last,都用聚合函数MAX,分析一下MAX的作用
select
deptno,
empno,
max(sal) over(partition by deptno) as 最高工资,
empname,
sal
from emp
where deptno = 3
order by 1,5 desc
根据表中的数据,工资最高的有两个人,加上first和last语句
select deptno,
empno,
empname,
sal,
to_char(wmsys.wm_concat(empname) keep(dense_rank last order by sal) over(partition by deptno)) as 工资最高的人,
min(empname) keep(dense_rank last order by sal) over(partition by deptno) as 工资最高的人min,
max(empname) keep(dense_rank last order by sal) over(partition by deptno) as 工资最高的人max
from emp
where deptno = 3
order by 1,4 desc
编码为3的部门工资最高的有两个,通过查询结果,可以看到keep()得到的结果包含两个人名字,所以通过min和max可以取到不同的值。
8.first_value
用first_value 和 last_value 来替换 first 和 last
select
deptno,
empno,
first_value(empname) over(partition by deptno order by sal desc) as 工资最高的人,
empname,
sal
from emp where deptno = 3
order by 1,5 desc
上面sql的结果没有问题
9.求总和的百分比
需求:计算各部门的工资合计,及该合计工资占总公司的比例
(1)分组汇总
select deptno,sum(sal) 工资合计 from emp group by deptno
(2)通过分析函数获取总合计
select deptno,工资合计,sum(工资合计) over() as 总合计
from (select deptno,sum(sal) 工资合计 from emp group by deptno) x;
(3)通过前两步的结果计算
select
deptno,
工资合计,
round((工资合计/总合计)*100,2) as 工资比例
from (
select deptno,工资合计,sum(工资合计) over() as 总合计
from (select deptno,sum(sal) 工资合计 from emp group by deptno) x) y;
也可以用专门的比例函数“ratio_to_report”
select deptno,
round(ratio_to_report(工资合计)over() * 100,2) as 工资比例
from(select deptno,sum(sal) 工资合计 from emp group by deptno)
order by 1
同其他分析函数一样,可以使用partition by 分组计算,如查询各员工占本部门的工资比例:
select deptno,
empname,
sal,
round(ratio_to_report(sal) over(partition by deptno)*100,2) as 工资比例
from emp
order by 1,2
相关推荐
- 前端入门——css 网格轨道详细介绍
-
上篇前端入门——cssGrid网格基础知识整体大概介绍了cssgrid的基本概念及使用方法,本文将介绍创建网格容器时会发生什么?以及在网格容器上使用行、列属性如何定位元素。在本文中,将介绍:...
- Islands Architecture(孤岛架构)在携程新版首页的实践
-
一、项目背景2022,携程PC版首页终于迎来了首次改版,完成了用户体验与技术栈的全面升级。作为与用户连接的重要入口,旧版PC首页已经陪伴携程走过了22年,承担着重要使命的同时,也遇到了很多问题:维护/...
- HTML中script标签中的那些属性
-
HTML中的<script>标签详解在HTML中,<script>标签用于包含或引用JavaScript代码,是前端开发中不可或缺的一部分。通过合理使用<scrip...
- CSS 中各种居中你真的玩明白了么
-
页面布局中最常见的需求就是元素或者文字居中了,但是根据场景的不同,居中也有简单到复杂各种不同的实现方式,本篇就带大家一起了解下,各种场景下,该如何使用CSS实现居中前言页面布局中最常见的需求就是元...
- CSS样式更改——列表、表格和轮廓
-
上篇文章主要介绍了CSS样式更改篇中的字体设置Font&边框Border设置,这篇文章分享列表、表格和轮廓,一起来看看吧。1.列表List1).列表的类型<ulstyle='list-...
- 一文吃透 CSS Flex 布局
-
原文链接:一文吃透CSSFlex布局教学游戏这里有两个小游戏,可用来练习flex布局。塔防游戏送小青蛙回家Flexbox概述Flexbox布局也叫Flex布局,弹性盒子布局。它决定了...
- css实现多行文本的展开收起
-
背景在我们写需求时可能会遇到类似于这样的多行文本展开与收起的场景:那么,如何通过纯css实现这样的效果呢?实现的难点(1)位于多行文本右下角的展开收起按钮。(2)展开和收起两种状态的切换。(3)文本...
- css 垂直居中的几种实现方式
-
前言设计是带有主观色彩的,同样网页设计中的css一样让人摸不头脑。网上列举的实现方式一大把,或许在这里你都看到过,但既然来到这里我希望这篇能让你看有所收获,毕竟这也是前端面试的基础。实现方式备注:...
- WordPress固定链接设置
-
WordPress设置里的最后一项就是固定链接设置,固定链接设置是决定WordPress文章及静态页面URL的重要步骤,从站点的SEO角度来讲也是。固定链接设置决定网站URL,当页面数少的时候,可以一...
- 面试发愁!吃透 20 道 CSS 核心题,大厂 Offer 轻松拿
-
前端小伙伴们,是不是一想到面试里的CSS布局题就发愁?写代码时布局总是对不齐,面试官追问兼容性就卡壳,想跳槽却总被“多列等高”“响应式布局”这些问题难住——别担心!从今天起,咱们每天拆解一...
- 3种CSS清除浮动的方法
-
今天这篇文章给大家介绍3种CSS清除浮动的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。首先,这里就不讲为什么我们要清楚浮动,反正不清除浮动事多多。下面我就讲3种常用清除浮动的...
- 2025 年 CSS 终于要支持强大的自定义函数了?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1.什么是CSS自定义属性CSS自...
- css3属性(transform)的一个css3动画小应用
-
闲言碎语不多讲,咱们说说css3的transform属性:先上效果:效果说明:当鼠标移到a标签的时候,从右上角滑出二维码。实现方法:HTML代码如下:需要说明的一点是,a链接的跳转需要用javasc...
- CSS基础知识(七)CSS背景
-
一、CSS背景属性1.背景颜色(background-color)属性值:transparent(透明的)或color(颜色)2.背景图片(background-image)属性值:none(没有)...
- CSS 水平居中方式二
-
<divid="parent"><!--定义子级元素--><divid="child">居中布局</div>...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- maven镜像 (69)
- undefined reference to (60)
- zip格式 (63)
- oracle over (62)
- date_format函数用法 (67)
- 在线代理服务器 (60)
- shell 字符串比较 (74)
- x509证书 (61)
- localhost (65)
- java.awt.headless (66)
- syn_sent (64)
- settings.xml (59)
- 弹出窗口 (56)
- applicationcontextaware (72)
- my.cnf (73)
- httpsession (62)
- pkcs7 (62)
- session cookie (63)
- java 生成uuid (58)
- could not initialize class (58)
- beanpropertyrowmapper (58)
- word空格下划线不显示 (73)
- jar文件 (60)
- jsp内置对象 (58)
- makefile编写规则 (58)