今天认识了下partition by 和group by

本文介绍了如何使用 Oracle SQL 中的 partition by 函数来解决一个具体的问题:查询各科成绩前三名的记录。通过示例代码展示了 partition by 的强大之处,并对比了其与 group by 的不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天学习Oracle  sql语句时碰到了这样的题目:

查询各科成绩前三名的记录:(不考虑成绩并列情况)

略看题目,以为能弄出来,下手写时才发现不是那样的

经过一番查阅后,才知道,还有partition by这个分区函数,这个函数貌似和group by 差不多,但仔细分析,partition却能做到group by不能做到的功能,比如说这题:

答案这样的:select * from  (select sno,cno,score ,row_number() over (partition by cno order by score desc)rn from sc) where  rn<4;

原来,partition 能按照指定的列把查询结果集给分成不同的区

 

暂时只理解到这里,以后在重新理理吧!

在SQL中,`PARTITION BY``GROUP BY`是两个常用于数据分析的子句,但它们的功能、语义使用场景有显著差异。 ### `GROUP BY` 的作用使用场景 `GROUP BY` 用于将结果集按照一个或多个列进行分组,通常聚合函数(如 `SUM`, `COUNT`, `AVG`, `MAX`, `MIN` 等)一起使用,以便对每个分组进行聚合计算。每个分组最终只返回一行数据。 例如,以下查询统计每个部门的平均工资: ```sql SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id; ``` 这种方式适用于需要对数据进行归类汇总的场景,如报表统计、数据聚合分析等[^2]。 ### `PARTITION BY` 的作用使用场景 `PARTITION BY` 是窗口函数(Window Function)的一部分,用于定义窗口函数的分区范围。它不会减少结果集的行数,而是在每个分区内独立地执行计算,保留原始数据行,并为每一行返回一个计算结果。 例如,以下查询为每个员工计算其所在部门的平均工资,同时保留员工的原始信息: ```sql SELECT employee_id, department_id, salary, AVG(salary) OVER (PARTITION BY department_id) AS avg_salary FROM employees; ``` 该方式适用于需要在分组内进行复杂计算但又不想丢失原始数据行的场景,如排名、累计求、移动平均等分析任务[^1]。 ### 两者的区别总结 | 特性 | `GROUP BY` | `PARTITION BY` | |-----------------------|-----------------------------------------|------------------------------------------| | 是否减少行数 | 是,每个分组只返回一行 | 否,保留原始数据行 | | 适用函数 | 聚合函数 | 窗口函数(如 `ROW_NUMBER`, `RANK`, `AVG` 等) | | 是否保留原始数据行 | 否 | 是 | | 典型应用场景 | 数据汇总、报表统计 | 窗口计算、排名、分组内分析 | ### 示例对比 假设有一个 `employees` 表,数据如下: | employee_id | department_id | salary | |-------------|---------------|--------| | 1 | 100 | 5000 | | 2 | 100 | 6000 | | 3 | 200 | 7000 | | 4 | 200 | 8000 | 使用 `GROUP BY` 查询部门平均工资: ```sql SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id; ``` 结果: | department_id | avg_salary | |---------------|------------| | 100 | 5500 | | 200 | 7500 | 使用 `PARTITION BY` 查询员工工资部门平均工资的对比: ```sql SELECT employee_id, department_id, salary, AVG(salary) OVER (PARTITION BY department_id) AS avg_salary FROM employees; ``` 结果: | employee_id | department_id | salary | avg_salary | |-------------|---------------|--------|------------| | 1 | 100 | 5000 | 5500 | | 2 | 100 | 6000 | 5500 | | 3 | 200 | 7000 | 7500 | | 4 | 200 | 8000 | 7500 | ### 使用建议 - 如果目标是生成汇总数据,使用 `GROUP BY`。 - 如果需要在保留原始数据的同时进行分组计算,使用 `PARTITION BY` 窗口函数结合[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值