我是使用分析函数的新手。

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,
       emp,
       salary
from
       (
       SELECT dept, 
              emp,
              salary,
              Min(salary) Over (Partition By dept) min_salary
       FROM   mytable
       )
where salary = min_salary
/

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

Oracle 可能有一个代码路径来识别在这种情况下实际上不需要计算排名,但我不会打赌。

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

其他提示

我觉得你很接近你的原始查询。下面将运行并做符合您的测试用例:

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

在此相反的RANK()的解决方案,在每个部门最多一个行这一个保证。但是,这暗示了一个问题:在有关于最低工资的两名员工一个部门,会发生什么?该RANK()解决方案将同时返回的员工 - 多行的部门。这个答案将挑选一个任意并确保只有一个有针对的部门。

可以使用RANK()语法。例如,这个查询将告诉你在哪里雇员他们对于部门内行列,他们的工资有多大:

SELECT
  dept,
  emp,
  salary,
  (RANK() OVER (PARTITION BY dept ORDER BY salary)) salary_rank_within_dept
FROM EMPLOYEES

然后,您可以从该查询,其中salary_rank_within_dept = 1

SELECT * FROM
  (
    SELECT
      dept,
      emp,
      salary,
      (RANK() OVER (PARTITION BY dept ORDER BY salary)) salary_rank_within_dept
    FROM EMPLOYEES
  )
WHERE salary_rank_within_dept = 1
select e2.dept, e2.emp, e2.salary
from employee e2
where e2.salary = (select min(e1.salary) from employee e1)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top