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

1 ... 48 49 50 [ 51 ] 52 53 54 ... 219


DEPTNO

EMPS

CLARK

KING

MILLER

SMITH

ADAMS

FORD

SCOTT

JONES

ALLEN

BLAKE

MARTIN

JAMES

TURNER

WARD

получить следующее результирующее множество:

DEPTNO EMPS

10 CLARK,KING,MILLER

20 SMITH,JONES,SCOTT,ADAMS,FORD

30 ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES

Решение

Каждая СУБД требует индивидуального подхода к этой проблеме. Ключ к решению - применение встроенных функций СУБД. Знание доступных возможностей позволит, используя функциональность СУБД и творческий подход, решить задачу, которая обычно не ставится в SQL.

Для построения списка с разделителями используйте рекурсивный WITH:

1 with x (deptno, cnt, list, empno, len)

2 as (

3 select deptno, count(*) over (partition by deptno),

4 cast(ename as varchar(100)), empno, 1

5 from emp

6 union all

7 select x.deptno, x.cnt, x.list , e.ename, e.empno, x.len+1

8 from emp e, x

9 where e.deptno = x.deptno

10 and e.empno > x. empno

11 )

12 select deptno,list

13 from x

14 where len = cnt



MySQL

Для построения списка с разделителями используйте встроенную

функцию GROUP CONCAT:

1 select deptno,

2 group concat(ename order by empno separator ,) as emps

3 from emp

4 group by deptno

Oracle

Для построения списка с разделителями используйте встроенную функцию SYS CONNECT BY PATH:

1 select deptno,

2 ltrim(sys connect by path(ename ) ) emps

3 from (

4 select deptno,

5 ename,

6 row number() over

7 (partition by deptno order by empno) rn,

8 count(*) over

9 (partition by deptno) cnt

10 from emp

11 )

12 where level = cnt

13 start with rn = 1

14 connect by prior deptno = deptno and prior rn = rn-1

PostgreSQL

PostgreSQL не предлагает стандартной встроенной функции для создания списка с разделителями, поэтому количество значений в списке должно быть известно заранее. Зная предполагаемый максимальный размер списка, можно определить, сколько значений требуется добавить, чтобы создать список, используя стандартные перестановку и конкатенацию:

select

deptno,

rtrim(

max(case

when pos=1 then

emps

else

end)

max(case

when pos=2 then

emps

else

end)

max(case

when pos=3 then

emps

else

end)

max(case

when pos=4 then

emps

else

end)

max(case

when pos=5 then

emps

else

end)

max(case

when pos=6 then

emps

else

end)

) as emps

from

select

a.deptno,

a.ename,

as emps,

d.cnt,

(select count(*) from emp b



where a.deptno=b.deptno and b.empno

from

emp a,

(select deptno, count(ename) as cnt

from emp

group by deptno) d

where

d.deptno=a.deptno

group

by deptno

order

by 1

SQL Server

Для построения списка с разделителями используйте рекурсивный

WITH:

with x (deptno, cnt, list, empno, len)

select

deptno, count(*) over (partition by deptno),

cast(ename as varchar(100)),

empno,

from

union

select

x.deptno, x.cnt,

cast(x.list + , + e.ename as varchar(100)),

e.empno, x.len+1

from

emp e, x

where

e.deptno = x.deptno

e.empno > x. empno

select

deptno,list

from

where

len = cnt

order

by 1

Обсуждение

Умение создавать списки с разделителями в SQL пригодится, поскольку необходимость в этом возникает довольно часто. Пока что для построения таких списков в SQL каждая СУБД предлагает собственный уникальный метод. Между решениями разных производителей мало общего; техники варьируются от использования рекурсии до иерархических функций, классической перестановки и агрегации.

DB2 и SQL Server

Решения для этих двух баз данных немного различаются в синтаксисе (для DB2 оператор конкатенации - , для SQL Server - + ), но методика одна. Первый запрос в конструкции WITH (верхняя часть UNION ALL) возвращает следующие данные для каждого служащего: отдел, количество служащих в отделе, имя, ID и константу 1 (которая в данный момент никак не используется). Во втором запросе (нижняя



1 ... 48 49 50 [ 51 ] 52 53 54 ... 219

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