|
Программирование >> Преобразование значений null
Ранжируются все служащие, затем их дубликаты. Результирующее множество содержит дубликаты всех служащих из таблицы IT APP, а также их ранги и значения DEPTNO. Все эти лишние строки необходимы, потому что в результирующем множестве мы должны иметь место для вставки значений DEPTNO в столбец ENAME. В результате декартова произведения IT APPS и таблицы в одну строку лишних строк не появится (потому что кардинальность любой таблицы х 1= кардинальности данной таблицы). Следующий шаг - полученное результирующее множество развернуть таким образом, чтобы все значения ENAME располагались в одном столбце, но были разделены по отделам соответствующими значениями DEPTNO. Из следующего запроса видно, как это происходит: select 1 flag1, 1 flag2, decode(rn,1,to char(deptno), ename) it dept from ( select x.*, y.id, row number()over(partition by x.deptno order by y.id) rn from ( select deptno deptno, ename, count(*)over(partition by deptno) cnt from it apps ) x, (select level id from dual connect by level <= 2) y ) z where rn <= cnt+1 FLAG1 FLAG2 IT DEPT 1 1 400 1 1 MAYWEATHER 1 1 CASTILLO 1 1 MARQUEZ 1 1 MOSLEY 1 1 CORRALES 1 1 500 1 1 CALZAGHE 1 1 GATTI 1 1 600 1 1 HAGLER 1 1 HEARNS 1 1 FRAZIER 1 1 LAMOTTA 1 1 700 1 1 JUDAH 1 1 MARGARITO 1 1 GUINN FLAG1 и FLAG2 начнут действовать позже, поэтому пока обратим внимание на столбец ITDEPT. Для каждого значения DEPTNO возвращено CNT*2 строк, но необходимо было получить CNT+1 строк, как обозначено предикатом WHERE. Поле RN - это ранг служащего. Были выбраны строки, ранг которых меньше или равен CNT +1; т. е. все служащие каждого отдела плюс один (этот дополнительный служащий - служащий с первым рангом в своем DEPTNO). В эту дополнительную строку и будет помещено значение DEPTNO. С помощью функции DECODE (старая функция Oracle, являющаяся в той или иной мере эквивалентом выражению CASE) мы обрабатываем значение RN и помещаем значение DEPTNO в результирующее множество. Служащий, находившийся в первой позиции (на основании значения RN), по-прежнему присутствует в результирующем множестве, но теперь его имя указано последним в списке (поскольку порядок не имеет значения, это не представляет проблемы). Вот довольно подробно, как работает нижняя часть UNION ALL. В верхней части UNION ALL происходит то же самое, что и в нижней, поэтому останавливаться на ней нет необходимости. Давайте лучше рассмотрим результирующее множество, возвращаемое при совмещении запросов: select 1 flag1, 0 flag2, decode(rn,1,to char(deptno), ename) it dept from ( select x.*, y.id, row number()over(partition by x.deptno order by y.id) rn from ( select deptno, ename, count(*)over(partition by deptno) cnt from it research ) x, (select level id from dual connect by level <= 2) y ) where rn <= cnt+1 union all select 1 flag1, 1 flag2, decode(rn,1,to char(deptno), ename) it dept from ( select x.*, y.id, row number()over(partition by x.deptno order by y.id) rn from ( select deptno deptno, ename, count(*)over(partition by deptno) cnt from it apps ) x, (select level id from dual connect by level <= 2) y ) where rn <= cnt+1 FLAG1 FLAG2 IT DEPT 0 100 JONES TONEY HOPKINS 0 200 P.WHITAKER MARCIANO ROBINSON MORALES 0 300 WRIGHT J.TAYLOR LACY 1 400 MAYWEATHER CASTILLO MARQUEZ MOSLEY CORRALES 1 500 CALZAGHE GATTI 1 600 HAGLER HEARNS FRAZIER LAMOTTA 1 700 JUDAH MARGARITO GUINN На данный момент назначение FLAG1 непонятно, но можно заметить, что FLAG2 показывает, в результате выполнения какой части UNION ALL получена строка (0 - верхней части, 1 - нижней).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |