SQL Oracle - 最佳查询

时间:2015-01-24 13:05:08

标签: sql oracle performance join

我有三个包含以下模式的表:

Persons(Person_id, Department_id, Sure_name, Name, Birthyear, Height, Manager_id)
Departments (Department_id, Department_Name, Code)
Salaries (Salary_id, Person_id, Salary)

我需要运行一个查询,该查询将显示部门的名称,而工作人员之间的差异是什么?最小和最大高度是最大的。

我是通过以下方式完成的:

select Department_Name
from Departments
where Department_id = (select Department_id
                      from Departments 
                      join Persons 
                      using (Department_id)
                      group by Department_id
                      having max(height) - min(height) = (select max(max(height) - min(height)) 
                                                          from Departments 
                                                          join Persons 
                                                          using (Department_id) 
                                                          group by Department_id));

它工作正常,只是我不确定解决方案是否最佳,这里有两个嵌套查询,我想知道我是否能以更简单的方式实现相同的目标。

2 个答案:

答案 0 :(得分:1)

试试这个。

SELECT Department_Name
FROM   Departments D
       INNER JOIN (SELECT Department_id,
                          Max(height) - Min(height) AS diff
                   FROM   Departments
                          JOIN Persons
                            ON using (Department_id)
                   WHERE ROWNUM = 1
                   GROUP  BY Department_id
                   ORDER  BY diff DESC) B
               ON d.Department_id = b.Department_id 

或使用Window Function

SELECT Department_id,
       Department_Name
FROM   (SELECT Row_number()OVER(ORDER BY Max(height)- Min(height) desc ) rn,
               Department_id,
               Department_Name
        FROM   Departments
               JOIN Persons
                 ON using(Department_id)
        GROUP  BY Department_id,
                  Department_Name)a
WHERE  rn = 1 

答案 1 :(得分:0)

这可能对您有用,有点复杂,但使用分析函数RANK()可能会简化使用除了聚合之外的东西:

SELECT d.department_id, d.department_name, d.code, p1.height_diff
  FROM departments d INNER JOIN (
    SELECT department_id, height_diff, RANK() OVER ( ORDER BY height_diff DESC ) AS rn
      FROM (
        SELECT department_id, MAX(height) - MIN(height) AS height_diff
          FROM Persons
         GROUP BY department_id
      )
  ) p1
    ON d.department_id = p1.department_id
 WHERE p1.rn = 1;

Please see SQL Fiddle demo here. N.B。我以前订购错误,现已更正为DESC