【问题标题】:SQL Oracle - optimum querySQL Oracle - 最佳查询
【发布时间】:2015-03-23 10:14:16
【问题描述】:

我有三个具有以下架构的表:

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));

而且效果很好,只是我不确定解决方案是否最佳,这里有两个嵌套查询,我想知道我是否可以用更简单的方式实现。

【问题讨论】:

    标签: sql oracle performance join


    【解决方案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 
    

    【讨论】:

    • 您甚至可以另外按部门名称分组以省略外部连接
    • 内部联接是否等同于联接?另外,我认为“限制”不适用于 Oracle。
    • @user4359659 - Join 等于 Inner Join。添加了另一个答案
    • 我不太确定可以将聚合放在窗口函数的OVER( ) 子句中。你不会想PARTITION BY department_id
    • @DavidFaber - 是的 partition by 这里不需要。据我所知,您可以在 order by 中使用聚合
    【解决方案2】:

    这可能对你有用,有点复杂,但使用分析函数 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. 注意我之前点错了,现在更正为DESC

    【讨论】:

    • 正在编辑...缺少右括号。
    猜你喜欢
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 2012-10-26
    • 2012-09-26
    相关资源
    最近更新 更多