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

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


1 select dept.deptno,

2 case dept.deptno

3 when 10 then emp cnts.deptno 10

4 when 20 then emp cnts.deptno 20

5 when 30 then emp cnts.deptno 30

6 end as counts by dept

7 from (

8 select sum(case when deptno=10 then 1 else 0 end) as deptno 10,

9 sum(case when deptno=20 then 1 else 0 end) as deptno 20,

10 sum(case when deptno=30 then 1 else 0 end) as deptno 30

11 from emp

12 ) emp cnts,

13 (select deptno from dept where deptno <= 30) dept

Обсуждение

Вложенный запрос EMP CNTS является денормализованным представлением, или широким результирующим множеством, которое требуется преобразовать в строки. Оно показано ниже:

select sum(case when deptno=10 then 1 else 0 end) as deptno 10,

sum(case when deptno=20 then 1 else 0 end) as deptno 20,

sum(case when deptno=30 then 1 else 0 end) as deptno 30 from emp

DEPTNO 10 DEPTNO 20 DEPTNO 30 3 5 6

Поскольку здесь три столбца, будет создано три строки. Начнем с декартова произведения между вложенным запросом EMP CNTS и некоторым табличным выражением, имеющим, по крайней мере, три строки. В следующем коде для создания декартова произведения используется таблица DEPT. В DEPT четыре строки:

select dept.deptno,

emp cnts.deptno 10, emp cnts.deptno 20, emp cnts.deptno 30 from (

select sum(case when deptno=10 then 1 else 0 end) as deptno 10, sum(case when deptno=20 then 1 else 0 end) as deptno 20, sum(case when deptno=30 then 1 else 0 end) as deptno 30 from emp

) emp cnts,

(select deptno from dept where deptno <= 30) dept

DEPTNO DEPTNO 10 DEPTNO 20 DEPTNO 30

10 3 5 6

20 3 5 6

30 3 5 6



Декартово произведение позволяет получить по строке для каждого столбца вложенного запроса EMP CNTS. Поскольку в окончательное результирующее множество должны войти только значения DEPTNO и количество служащих в соответствующем DEPTNO, используем выражение CASE для преобразования трех столбцов в один:

select dept.deptno,

case dept.deptno

when 10 then emp cnts.deptno 10 when 20 then emp cnts.deptno 20 when 30 then emp cnts.deptno 30 end as counts by dept from (

select sum(case when deptno=10 then 1 else 0 end) as deptno 10, sum(case when deptno=20 then 1 else 0 end) as deptno 20, sum(case when deptno=30 then 1 else 0 end) as deptno 30 from emp

) emp cnts,

(select deptno from dept where deptno <= 30) dept

DEPTNO COUNTS BY DEPT

10 3

20 5

30 6

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

Задача

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

EMPS

CLARK

MANAGER

2450

KING

PRESIDENT

5000

MILLER

CLERK

1300



Решение

Ключ к решению - использовать декартово произведение и возвратить по четыре строки для каждого служащего. Это позволит разместить значения столбцов в отдельных строках и разделить значения, относящиеся к разным служащим, пустыми строками.

DB2, Oracle и SQL Server

С помощью ранжирующей функции ROW NUMBER OVER присвойте каждой строке ранг на основании значений EMPNO (1-4). Затем используйте выражение CASE для преобразования трех столбцов в один:

1 select case rn

2 when 1 then ename

3 when 2 then job

4 when 3 then cast(sal as char(4))

5 end emps

6 from (

7 select e.ename,e.job,e.sal,

8 row number()over(partition by e.empno

9 order by e.empno) rn

10 from emp e,

11 (select *

12 from emp where job=CLERK) four rows

13 where e.deptno=10

14 ) x PostgreSQL и MySQL

Данный рецепт призван обратить внимание на применение ранжирующих функций для ранжирования строк, которое затем используется при разворачивании таблицы. На момент написания данной книги ни PostgreSQL, ни MySQL не поддерживают ранжирующие функции.

Обсуждение

DB2, Oracle и SQL Server

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

select e.ename,e.job,e.sal,

row number()over(partition by e.empno

order by e.empno) rn

from emp e where e.deptno=10

ENAME JOB SAL RN

CLARK MANAGER 2450 1

KING PRESIDENT 5000 1

MILLER CLERK 1300 1



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

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