Программирование >>  Преобразование значений null 

1 ... 137 138 139 [ 140 ] 141 142 143 ... 219


CLERK

SMITH

SALESMAN

ALLEN

SALESMAN

WARD

MANAGER

JONES

SALESMAN

MARTIN

MANAGER

BLAKE

MANAGER

CLARK

ANALYST

SCOTT

PRESIDENT

KING

SALESMAN

TURNER

CLERK

ADAMS

CLERK

JAMES

ANALYST

FORD

CLERK

MILLER

Присвоение каждому сочетанию JOB/ENAME уникального ранга делает каждую строку уникальной. Даже если есть служащие, имеющие одинаковые имена и занимающие одну должность, не будет двух служащих с одним рангом для данной должности. Этот шаг является самым важным при решении задачи. Если не выполнить этот первый шаг, внешний запрос в результате агрегации удалит нужные строки. Рассмотрим, как выглядело бы результирующее множество без присвоения ранга каждому сочетанию JOB/ENAME, если бы применялась техника, представленная в первом рецепте:

max(case

when

job=CLERK

then

ename else null

end)

as clerks,

max(case

when

job=ANALYST

then

ename else null

end)

as analysts,

max(case

when

job=MANAGER

then

ename else null

end)

as mgrs,

max(case

when

job=PRESIDENT

then

ename else null

end)

as prez,

max(case

when

job=SALESMAN

then

ename else null

end)

as sales

CLERKS ANALYSTS MGRS PREZ SALES

SMITH SCOTT JONES KING WARD

К сожалению, для каждого значения JOB возвращена только одна строка: служащий с наивысшим рангом. При разворачивании результирующего множества функции MIN или MAX должны использоваться только как средства для удаления значений NULL, без ограничения возвращаемых значений ENAME.

Теперь, когда ясен смысл назначения рангов, можно идти далее. Следующий шаг - использовать выражение CASE для распределения значений ENAME по соответствующим столбцам (JOB):

select rnk,

case when job=CLERK



then

ename else null

as clerks,

case when

job=ANALYST

then

ename else null

as analysts,

case

when

job=MANAGER

then

ename else null

as mgrs,

case

when

job=PRESIDENT

then

ename else null

as prez,

case

when

job=SALESMAN

then

ename else null

as sales

from ( select e.job, e.ename,

(select count(*) from emp d where e.job=d.job and e.empno < d.empno) as rnk from emp e ) x

RNK CLERKS ANALYSTS MGRS PREZ SALES 3 SMITH

3 ALLEN

2 WARD

2 JONES

1 MARTIN

1 BLAKE

0 CLARK

1 SCOTT

0 KING

0 TURNER

2 ADAMS

1 JAMES

0 FORD 0 MILLER

На данный момент строки транспонированы в столбцы, осталось лишь удалить значения NULL, чтобы сделать результирующее множество более удобным для восприятия. Удаляем значения NULL с помощью агрегатной функции MAX и группируем результаты по RNK. (Выбор MAX произволен. Можно использовать и функцию MIN.) Сочетания значений RN/JOB/ENAME уникальны, поэтому агрегатная функция просто удалит значения NULL:

select max(case

when

job=CLERK

then

ename else null

end)

as clerks,

max(case

when

job=ANALYST

then

ename else null

end)

as analysts,

max(case

when

job=MANAGER

then

ename else null

end)

as mgrs,

max(case

when

job=PRESIDENT

then

ename else null

end)

as prez,

max(case

when

job=SALESMAN

then

ename else null

end)

as sales



3 5 6

Оно должно быть преобразовано к такому виду:

DEPTNO COUNTS BY DEPT

10 3

20 5

30 6

Решение

Чтобы получить требуемое результирующее множество, можно просто выполнить операции COUNT и GROUP BY для таблицы EMP. Однако главное здесь - понимать, что данные не хранятся как строки; возможно, данные денормализованы и агрегированные значения хранятся как множество столбцов.

Чтобы преобразовать столбцы в строки, используйте декартово произведение. Сколько столбцов требуется преобразовать в строки, должно быть известно заранее, потому что кардинальность табличного выражения, используемого для создания декартова произведения, должна, как минимум, равняться числу транспонируемых столбцов.

Мы не будем создавать денормализованную таблицу данных. В решении данного рецепта применим решение из первого рецепта главы и создадим широкое результирующее множество. Вот полное решение:

from ( select e.job, e.ename,

(select count(*) from emp d where e.job=d.job and e.empno < d.empno) as rnk from emp e ) x

group by rnk

CLERKS ANALYSTS MGRS PREZ SALES

MILLER FORD CLARK KING TURNER

JAMES SCOTT BLAKE MARTIN

ADAMS JONES WARD SMITH ALLEN

Обратное разворачивание результирующего множества

Задача

Требуется преобразовать столбцы в строки. Рассмотрим следующее результирующее множество:

DEPTNO 10 DEPTNO 20 DEPTNO 30



1 ... 137 138 139 [ 140 ] 141 142 143 ... 219

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика