Оптимизация Oracle SQL Query - PullRequest
       11

Оптимизация Oracle SQL Query

0 голосов
/ 21 апреля 2011

Вот мой запрос, который возвращает цепочку супервизоров для сотрудника, но использует несколько вложенных операторов 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';

значок = идентификатор сотрудника
supervisor_badge = значок руководителя работника
остальные поля находятся в таблице hr_data

           badge    supervisor_badge 
           123456   111111
           111111   454545
           454545   332211

вывод

 employee       boss1      boss2      boss3
 123456         111111     454545     332211

Ответы [ 2 ]

1 голос
/ 21 апреля 2011

У меня нет базы данных под рукой, чтобы смоделировать это, так что я сделаю это.Я попытался использовать ваши же соглашения об именах, для ясности.

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 .

1 голос
/ 21 апреля 2011

Использование объединений, а не подзапросов.

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

Поскольку уровень является переменным, вы можете рассмотреть возможность использования хранимой процедуры для внутреннего цикла для заданного числа уровней (пока он не достигнет вершины, например, ваш генеральный директор).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...