加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql – 用于分组中最小值的Oracle Analytic函数

发布时间:2020-12-12 06:47:08 所属栏目:MsSql教程 来源:网络整理
导读:我是处理分析功能的新手. DEPT EMP SALARY---- ----- ------ 10 MARY 100000 10 JOHN 200000 10 SCOTT 300000 20 BOB 100000 20 BETTY 200000 30 ALAN 100000 30 TOM 200000 30 JEFF 300000 我希望部门和员工的薪水最低. 结果应如下所示: DEPT EMP SALARY---
我是处理分析功能的新手.
DEPT EMP   SALARY
---- ----- ------
  10 MARY  100000
  10 JOHN  200000
  10 SCOTT 300000
  20 BOB   100000
  20 BETTY 200000
  30 ALAN  100000
  30 TOM   200000
  30 JEFF  300000

我希望部门和员工的薪水最低.

结果应如下所示:

DEPT EMP   SALARY
---- ----- ------
  10 MARY  100000
  20 BOB   100000
  30 ALAN  100000

编辑:这是我的SQL(当然,它不起作用,因为它也希望group by子句中的人员):

SELECT dept,emp,MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY salary)
FROM mytable
GROUP BY dept

解决方法

我认为Rank()函数不是这样的,有两个原因.

首先,它可能比基于Min()的方法效率低.

原因是查询必须在扫描数据时维护每个部门所有工资的有序列表,然后通过重新读取此列表来分配等级.显然,如果没有可用于此的索引,则在读取最后一个数据项之前无法分配排名,并且列表的维护成本很高.

因此,Rank()函数的性能取决于要扫描的元素总数,如果数量足以使排序溢出到磁盘,则性能将崩溃.

这可能更有效:

select dept,salary
from
       (
       SELECT dept,salary,Min(salary) Over (Partition By dept) min_salary
       FROM   mytable
       )
where salary = min_salary
/

此方法仅要求查询为每个部门保留到目前为止遇到的最小值的单个值.如果遇到新的最小值,则修改现有值,否则丢弃新值.必须在内存中保留的元素总数与部门数量有关,而不是与扫描的行数有关.

可能是Oracle有一个代码路径来识别在这种情况下不需要计算Rank,但我不打赌它.

不喜欢Rank()的第二个原因是它只是回答了错误的问题.问题不在于“当每个部门的工资按升序排序时,哪些记录的工资是第一个排名”,它是“哪个记录的薪水是每个部门的最低工资”.至少对我来说这是一个很大的不同.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读