Oracle-day6:over()函数

这篇具有很好参考价值的文章主要介绍了Oracle-day6:over()函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、over()开窗函数

二、无参over()的使用

三、over(partition by 列名)

四、over(order by 列名 asc/desc)

五、over(partition by 列名  order by 列名 asc|desc)

六、练习(笔试)


一、over()开窗函数

  拓展:数据库的版本
  oracle:8i 9i 10g 11g 12c 18c 19c
  mysql:5.x 8.0 (没有7.x、6.x)
  -- 一、开窗函数 over() ---
  over函数的使用:在select的子句中使用,语法:
  计算函数部分()  over(partition by 列名 order by 列名 asc|desc)  group by
  其中:
  1、计算函数部分:聚合函数、排名函数、平移函数等 只能是一个函数
  2、partition by :分组,不是必选项
  3、order by:排序,不是必选项
  4、over()函数有4种使用方法,即:参数二选一,不带参数,全带参数
*/

二、无参over()的使用

-- 一、开窗函数over()的第一种用法:over()
-- 1、计算函数部分() over():对整个表格进行计算
-- 例题一:查询emp表中的最高工资、最低工资、平均工资
select max(sal),min(sal),avg(sal) from emp
-- 注意:1、聚合函数在一个结果集中计算 返回值是一样  
--          2、over() 新生成的一个列 返回的行数是原来表的行数
select 
empno,sal,
max(sal) over() maxsal,
min(sal) over() minsal,
avg(sal) over() avgsal 
from emp;

 
-- 例题二、找出emp表中工资最高的员工信息
 ----方法1:子查询
   ---a.找出最高的工资
   select max(sal) from emp;  
  ---b.where条件子查询 单行值子查询
   select  * from  emp 
   where sal = (select max(sal) from emp) ;

 ----方法2:开窗函数+from 子查询
   ---a.开窗函数
    select emp.*,max(sal) over() maxsal from emp;
    ---b.from 子查询
    select  * from  
(select emp.*,max(sal) over() maxsal from emp)
    where sal = maxsal;

     ---with as语句
    with a as (select emp1.*,max(sal) over() maxsal from emp1)
    select  * from  a where sal = maxsal;

----方法3:开窗+from 条件子查询
    ---a.开窗
    select emp1.*,max(sal) over() maxsal,sal - max(sal) over() c from emp1;
    ---b.from 条件子查询
    select  * from  
    (select emp1.*,max(sal) over() maxsal,sal - max(sal) over() c from emp1)
where c = 0;

    ---with as 语句
    with a as (select emp1.*,max(sal) over() maxsal,sal - max(sal) over() c from emp1)
    select  * from  a where c = 0;
    
-- 练习三、计算emp表中每个员工你的工资和最高的比值是多少
select emp.*,max(sal) over(),sal/max(sal) over() from emp;
-- 练习四、计算emp表中每个员工的工资和最高工资的差值是多少?
select emp.*,max(sal) over(),sal-max(sal) over() from emp;

三、over(partition by 列名)

-- 使用方式二(带单个参数)、over(partition by 列名)
/*
   partition by 与 group by的区别
   group by会将结果集按照字段进行聚合,结果集会缩减,在统计部门人数,平均工资等会用到
   partition by 会对结果集按照指定字段分层排列,结果集不会缩减,如将公司全部人
*/

-- 在emp表中查询每个部门工资最高的员工信息
-- 1、找出每个部门的最高工资
-- group by 的写法
-- 1.1 对部门分组,同时要保持一致性
select deptno,max(sal)
from emp group by deptno
;
-- 1.2 多列子查询
select * from emp
where(deptno,sal) in(
    select deptno,max(sal)
    from emp group by deptno
)
;

-- 使用开窗函数 over()
-- 1.1 over()
select emp.*,
max(sal) over(partition by deptno) maxsal
from emp;
-- 查询到的数据并不会缩减,每个员工的信息都会多出一列当前部门的最高工资

-- 1.2 加上条件和from查询
select * from(
       select emp.*,
       max(sal) over(partition by deptno) maxsal
       from emp
)where sal = maxsal
;

-- with as写法
with a as(select emp.*,max(sal) over(partition by deptno) maxsal from emp)
select * from a where sal = maxsal;


-- 2、在emp表中计算每个人在部门工资总和中所占的比例
-- 2.1 over()开窗
select emp.*,
sum(sal) over(partition by deptno) sumsal 
from emp
;
-- 2.2 over开窗+form子查询
select * from(
        select emp.*,
        sum(sal) over(partition by deptno) sumsal 
        from emp
);

-- 2.3 求每个人在工资总和中的比例
select empno,ename,sal,sumsal,sal/sumsal
from(
        select emp.*,
        sum(sal) over(partition by deptno) sumsal 
        from emp
);


-- 2.4 四舍五入:round(值,保留小数位)
select empno,ename,sal,sumsal,round(sal/sumsal,2)
from(
        select emp.*,
        sum(sal) over(partition by deptno) sumsal 
        from emp
);

四、over(order by 列名 asc/desc)

   对整个表,对排序的列进行依次的累计运算,并列的名次和数据
   会当成一个整体进行计算(一次性计算)
   
   -- row_number():根据某个列,按照顺序进行排序 1、2、3、4
   -- rank():根据某个列,按照顺序进行排序,如果值相同,会出现并列的名次,会跳过占用的名次:1、2、2、4
   -- dense_rank():根据某个列,按照顺序进行排序,如果值相同,会出现并列的名次,不会跳过名次:1、2、2、3
   --rownum 取行号函数(系统关键字)只能 <= 不能 > 从1开始可以 >=

-- 1、对row_number列以sal排序
select emp.*,row_number() over(order by sal) from emp;

-- 2、对 rank()列以sal排序
select emp.*, rank() over(order by sal) from emp;

-- 3、对dense_rank()列以sal排序
select emp.*,dense_rank() over(order by sal) from emp;

-- 4、rownum 以sal升序排序(这个需要用到子查询)
select a.*,rownum r from
(select * from emp order by sal) a;


-- 5、练习:在成绩表中查询c001课程成绩的前6~10名


-- 5.1、查询到coo1的成绩排序
select * from sc_a01;
select sc_a01.*,row_number() over(partition by cno order by score desc)
from sc_a01
where cno = 'c001'
;

-- 5.2 合并子查询
select * from (
       select sc_a01.*,row_number() over(partition by cno order by score desc) r
       from sc_a01
       where cno = 'c001'
)where r between 6 and 10;

五、over(partition by 列名  order by 列名 asc|desc)

/*
   over(partition by 列名  order by 列名 asc|desc):
   在每个分组中,对排序的列进行依次的累计运算,并列的名次和数据,会当成一个整体进行计算
*/

-- 1、在emp表中,找出每个部门的最高工资,对应的员工信息
select * from (
       -- 子查询
       select emp.*,max(sal) over(partition by deptno order by sal desc) maxsal
       from emp
)where sal = maxsal;


-- 2、在emp表中找出每个部门的员工的工资和该部门最高工资的差值
select emp.*,max(sal) over(partition by deptno order by sal desc) maxsal,
sal-max(sal) over(partition by deptno order by sal desc) cha from emp;


-- 3、在成绩表中计算每门课程前 1-10名的信息
-- 3.1 对成绩做出排序
select a.*,row_number() over(partition by cno order by score desc) r 
from sc_a01 a
;

-- 3.2 合并子查询
select * from(
       select a.*,row_number() over(partition by cno order by score desc) r 
       from sc_a01 a
)where r between 1 and 10;


-- 4、在成绩表中计算每门课程前1-10名的总分
-- 4.1 已查询到每门课程的前10名
select * from(
       select a.*,row_number() over(partition by cno order by score desc) r 
       from sc_a01 a
)where r between 1 and 10;

-- 4.2 再此基础上加上分组计算
select cno,sum(score) from(
       select a.*,row_number() over(partition by cno order by score desc) r 
       from sc_a01 a
)
where r between 1 and 10
group by cno
;

select * from emp;
-- 5、在emp表中计算每个部门前六名的工资总和
select deptno,sum(sal) from(
       select e.*,row_number() over(partition by deptno order by sal desc) r
       from emp e
)
where r <= 60
group by deptno
;

六、练习(笔试)

Oracle-day6:over()函数,oracle,数据库文章来源地址https://www.toymoban.com/news/detail-693158.html

/*
      二、练习题
      -- case when 条件判断
      case
      when 条件判断1 then 条件为真
      when 条件判断2 then 条件为真
      ...
      else 所有条件都为假的时候
      end
      else 可以省略,可以生成一个或多个列
      
*/
-- 1、建表填入数据
create table info(
       id number,
       name varchar(20)
)
select * from info;
insert into info values(1,'/');
insert into info values(2,'A');
insert into info values(3,'B');
insert into info values(4,'C');
insert into info values(5,'/');
insert into info values(6,'D');
insert into info values(7,'E');
insert into info values(8,'/');
insert into info values(9,'F');
insert into info values(10,'C');
insert into info values(11,'H');


-- 方法一、
-- 1.1、筛选出不包含/的数据
select * from info where name <> '/';

-- 1.2、使用case when语句
select id,name,case
                         when id between 2 and 4 then 1
                         when id between 6 and 7 then 2
                         when id between 9 and 11 then 3
                         end group_id  
from info where name <> '/';


-- 方法二、
-- 2.1 单个结果的查询
select id,name,1 group_id from info where id between 2 and 4;
select id,name,2 group_id from info where id between 6 and 7;
select id,name,3 group_id from info where id between 9 and 11;

-- 2.2 拼接三个查询结果:使用 union all
select id,name,1 group_id from info where id between 2 and 4
union all
select id,name,2 group_id from info where id between 6 and 7
union all
select id,name,3 group_id from info where id between 9 and 11;


-- 方法三、开窗
-- 3.1 筛选没有 / 的
select id,name from info where name <> '/';

-- 3.2 对id排序
select id,name,row_number() over(order by id) r from info where name <> '/';

--- 3.3完善--用id-row_number 刚好就可以满足到题目条件,再以group_id分组
select 
id,name,row_number() over(order by id) r,id-row_number() over(order by id) group_id
from info 
where name <> '/'
;

到了这里,关于Oracle-day6:over()函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python从Oracle数据库中获取数据——fetchall(),fetchone(),fetchmany()函数功能分析

    Python从Oracle数据库中获取数据——fetchall(),fetchone(),fetchmany()函数功能分析 1、fetchall()函数,它的返回值是多个元组,即返回多个行记录,如果没有结果,返回的是() 2、fetchone()函数,它的返回值是单个的元组,也就是一行记录,如果没有结果,那就会返回None,每次向后抓取一条记录 3、

    2024年02月15日
    浏览(48)
  • 数据库SQL函数 根据身份证号/出生年月 精确计算年龄(Oracle/MySQL)

    问题 根据身份证号统计年龄(18位) Oracle 思路 (1)Substr()函数在Oracle使用中表示被劫取的字符串表达式,截取字符串的内容。 (2)To_date()函数可以转换不同格式的日期,通过使用to_date函数可以将字符串类型的日期转换成date格式。 (3)Months_between()函数反悔两个日期之间的

    2024年02月11日
    浏览(47)
  • Oracle数据库面试题 精选 Oracle 面试题

    1.解释冷备份和热备份的不同点以及各自的优点 冷备份 发生在数据库已经正常关闭的情况下,将关键性文件拷贝到另外位置的一种说法。适用于所有模式的数据库。 优点 1. 是非常快速的备份方法(只需拷贝文件) 2. 容易归档(简单拷贝即可) 3. 容易恢复到某个时间点上(只

    2024年02月05日
    浏览(99)
  • 【Oracle】收集Oracle数据库内存相关的信息

    【声明】文章仅供学习交流,观点代表个人,与任何公司无关。 编辑|SQL和数据库技术(ID:SQLplusDB) Oracle数据库包含多个内存区域,每个区域都包含多个子组件。 Oracle Database Memory Structures 根据具体问题的需要,可以通过如下命令收集Oracle数据库内存相关的信息。 例: 注:SET

    2024年01月21日
    浏览(67)
  • 【Oracle】使用 SQL Developer 连接 Oracle 数据库

    SQL Developer 是 Oracle 官方推出的一款免费的数据库开发工具,它提供了丰富的数据库开发功能,其中包括连接 Oracle 数据库的功能。 在本文中,我们将从多个方面详细阐述如何使用 SQL Developer 连接 Oracle 数据库。 在连接 Oracle 数据库前,需要需要做一些准备工作,包括安装 SQ

    2024年02月06日
    浏览(67)
  • Oracle数据库

    ①层次型数据库 ②网状型数据库 ③关系型数据库(主要介绍) E-R图:属性(椭圆形),实体(矩形),联系(菱形-一对一、一对多、多对多) 注:有的联系也有属性 关系型数据库的设计范式: 第一范式(1NF):属性不可再分,字段保证原子性 第二范式(2NF):在满足1

    2024年02月08日
    浏览(57)
  • Oracle 开发篇+Java通过HiKariCP访问Oracle数据库

    标签:HikariCP、数据库连接池、JDBC连接池、 释义:HikariCP 是一个高性能的 JDBC 连接池组件,号称性能最好的后起之秀,是一个基于BoneCP做了不少的改进和优化的高性能JDBC连接池。 ★ Java代码 ※ 如果您觉得文章写的还不错, 别忘了在文末给作者点个赞哦 ~

    2024年02月13日
    浏览(54)
  • Oracle数据库概念简介

    一般意义上的数据库包含两个部分 库:就是一个存储一堆文件的文件目录 数据库管理系统:管理库的系统 数据库管理系统(Database Management System),是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,简称 DBMS ; 它对数据库进行统一的管理和控制,以保证数

    2024年02月09日
    浏览(49)
  • Oracle数据库完整卸载

    进入计算机管理,在服务中,找到oracle开头的所有服务,右击选择停止。 快捷键:ctrl+shift+esc打开任务管理器 点击开始菜单找到Oracle,然后点击Oracle安装产品,再点击Universal Installer。 点击之后稍等一会然后会进入进入下图界面,点击卸载产品。 单击“卸载产品”,选中除“Or

    2024年01月16日
    浏览(63)
  • 快速监控 Oracle 数据库

    Oracle 数据库在行业内应用广泛,通常存放的非常重要的数据,监控是必不可少的,本文使用 Cprobe 采集 Oracle 监控数据,极致简单,分享给大家。 安装配置 Oracle 简单起见,我使用 Docker 启动 Oracle,命令如下: 如上命令启动之后,Oracle 的监听端口是 1521,用户名/密码是 syst

    2024年01月20日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包