优化Oracle SQL查询

时间:2011-04-21 17:15:28

标签: sql select nested query-optimization

这是我的一个查询,它返回一个员工的监督链,但它使用了一堆嵌套的SELECT语句。 我想知道这个查询是否可以重构以提高效率。该查询适用于3级管理层授权员工参加培训课程的应用程序。目前,我们需要3个级别的批准,但这可能会更改为4个或更多。

SELECT badge as employee, 
   supervisor_badge as boss1, 
   (select supervisor_badge FROM hr_data level2 WHERE badge = level1.supervisor_badge) as boss2
   (select supervisor_badge FROM hr_data level3 WHERE badge = 
           (select supervisor_badge FROM hr_data level2 WHERE badge = level1.supervisor_badge)) as boss3
   FROM hr_data level1 WHERE BADGE = '123456';

badge =员工的身份
supervisor_badge =员工主管的徽章
字段在hr_data表中

           badge    supervisor_badge 
           123456   111111
           111111   454545
           454545   332211

输出

 employee       boss1      boss2      boss3
 123456         111111     454545     332211

2 个答案:

答案 0 :(得分:1)

使用连接而不是子查询。

SELECT
    e.badge, b1.badge, b2.badge, b3.badge
FROM
    hr_data e
LEFT JOIN hr_data b1 ON e.badge=b1.badge
LEFT JOIN hr_data b2 ON b1.badge=b2.badge
LEFT JOIN hr_data b3 ON b2.badge=b3.badge
WHERE
    e.badge='123456';

由于级别是可变的,您可能需要考虑使用存储过程在内部循环以获得预定数量的级别(直到它达到顶级,例如,您的CEO)。

答案 1 :(得分:1)

我没有数据库方便,嘲笑这个,所以我会把它甩掉。为清楚起见,我尝试使用相同的命名约定。

SELECT   level1.badge as employee
        ,level2.badge as boss1
        ,level3.badge as boss2
        ,level3.supervisor_badge as boss3
FROM    hr_data level1 
        INNER JOIN hr_data level2 
            ON level2.badge = level1.supervisor_badge
        INNER JOIN hr_data level3 
            ON level3.badge = level2.supervisor_badge
WHERE       level1.badge = '123456'

重要说明:这只会返回所有联接中存在数据的记录。要返回少于3个老板的记录(即只有boss1和boss2,但没有boss3),请将 INNER JOIN 语句更改为 LEFT JOIN