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

1 ... 135 136 137 [ 138 ] 139 140 141 ... 219


ENAME

ANALYST

SCOTT

ANALYST

FORD

CLERK

SMITH

CLERK

ADAMS

CLERK

MILLER

CLERK

JAMES

MANAGER

JONES

MANAGER

CLARK

MANAGER

BLAKE

PRESIDENT

KING

SALESMAN

ALLEN

SALESMAN

MARTIN

SALESMAN

TURNER

SALESMAN

WARD

Хотелось бы отформатировать это множество так, чтобы каждая должность была представлена отдельным столбцом:

CLERKS ANALYSTS MGRS PREZ SALES

MILLER FORD CLARK KING TURNER

JAMES SCOTT BLAKE MARTIN

ADAMS JONES WARD

SMITH ALLEN

Решение

В отличие от первого рецепта данной главы данное результирующее множество состоит из нескольких строк. Техника, применявшаяся в предыдущем рецепте, здесь не подходит, потому что обеспечит возвращение MAX(ENAME) для каждого JOB, т. е. одного ENAME для каждого JOB (т. е. мы получим одну строку, как в первом рецепте). Чтобы решить поставленную задачу, необходимо сделать каждое сочетание JOB/ENAME уникальным. Тогда при использовании агрегатной функции для удаления значений NULL не будет утрачено ни одно значение ENAME.

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

Задача

Требуется преобразовать строки в столбцы, создавая для каждого значения заданного столбца отдельный столбец. Однако в отличие от предыдущего рецепта выведено должно быть несколько строк.

Например, требуется выбрать всех служащих и их должности (JOB). В нашем распоряжении имеется следующее результирующее множество:



DB2, Oracle и SQL Server

Используя ранжирующую функцию ROW NUMBER OVER, сделайте каждое сочетание JOB/ENAME уникальным. Разверните результирующее множество с помощью выражения CASE и агрегатной функции MAX, группируя при этом по значению, возвращенному ранжирующей функцией:

select max(case

when

]ob=CLERK

then

ename else null

end)

clerks,

max(case

when

]ob=ANALYST

then

ename else null

end)

analysts,

max(case

when

]ob=MANAGER

then

ename else null

end)

mgrs,

max(case

when

]ob=PRESIDENT

then

ename else null

end)

prez,

max(case

when

]ob=SALESMAN

then

ename else null

end)

sales

11 from (

12 select job,

13 ename,

14 row number()over(partition by job order by ename) rn

15 from emp

16 ) x

17 group by rn

PostgreSQL и MySQL

Скалярным подзапросом ранжируйте всех служащих по EMPNO. Разверните результирующее множество с помощью выражения CASE и агрегатной функции MAX, группируя при этом по значению, возвращенному скалярным подзапросом:

select max(case

when

job=CLERK

then

ename else null

end)

clerks,

max(case

when

job=ANALYST

then

ename else null

end)

analysts,

max(case

when

job=MANAGER

then

ename else null

end)

mgrs,

max(case

when

job=PRESIDENT

then

ename else null

end)

prez,

max(case

when

job=SALESMAN

then

ename else null

end)

sales

11 12 13 14 15 16 17 18

from (

select e.job,

e.ename, (select where from emp e ) x

group by rnk

count(*) from emp d

e.job=d.job and e.empno < d.empno) as rnk



Обсуждение

DB2, Oracle и SQL Server

Первый шаг - с помощью ранжирующей функции ROW NUMBER OVER сделать каждое сочетание JOB/ENAME уникальным:

select job, ename,

row number()over(partition by job order by ename) rn from emp

ENAME

ANALYST

FORD

ANALYST

SCOTT

CLERK

ADAMS

CLERK

JAMES

CLERK

MILLER

CLERK

SMITH

MANAGER

BLAKE

MANAGER

CLARK

MANAGER

JONES

PRESIDENT

KING

SALESMAN

ALLEN

SALESMAN

MARTIN

SALESMAN

TURNER

SALESMAN

WARD

Присвоение каждому ENAME уникального для данной должности номера строки предотвращает появление любых проблем, которые могли бы возникнуть в случае существования двух служащих с одинаковыми именем и должностью. Целью является обеспечение возможности группировки по номеру строки (по столбцу RN) без исключения служащих из результирующего множества из-за применения функции MAX. Данный шаг - самый важный в решении поставленной задачи. Если не выполнить этот первый шаг, внешний запрос в результате агрегации удалит нужные строки. Рассмотрим, как выглядело бы результирующее множество без использования функции ROW NUMBER OVER, если бы применялась техника, представленная в первом рецепте:

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

from emp



1 ... 135 136 137 [ 138 ] 139 140 141 ... 219

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