Объединение строк в несколько столбцов Oracle 10g - PullRequest
2 голосов
/ 08 марта 2011

Можно ли построить SQL для объединения значений столбцов из нескольких строк?

Ниже приведен пример:

Таблица A

PID
A
B
C

Таблица B

PID   SEQ    Desc

A     1      Have
A     2      a nice
A     3      day.
B     1      Nice Work.
C     1      Yes
C     2      we can 
C     3      do 
C     4      this work!

Вывод SQL должен быть -

PID   Desc

A     day.||a nice||Have
B     Nice Work.
C     this work!||do||we can||Yes

Таким образом, в основном столбец Desc для выходной таблицы представляет собой конкатенацию значений SEQ из таблицы B, и значения добавляются в порядке убывания SEQ и разделяются ||

Любая помощь с SQL?

К вашему сведению - поиск решения без использования функций или хранимых процедур

Ответы [ 4 ]

2 голосов
/ 08 марта 2011

С здесь

Но я бы пошел с функцией в любой день.

SQL> select deptno
  2       , rtrim(ename,',') enames
  3    from ( select deptno
  4                , ename
  5                , rn
  6             from emp
  7            model
  8                  partition by (deptno)
  9                  dimension by (row_number() over
 10                                (partition by deptno order by ename) rn
 11                               )
 12                  measures     (cast(ename as varchar2(40)) ename)
 13                  rules
 14                  ( ename[any] order by rn desc = ename[cv()]||','||ename[cv()+1]
 15                  )
 16         )
 17   where rn = 1
 18   order by deptno
 19  /

    DEPTNO ENAMES
---------- ----------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
1 голос
/ 08 марта 2011

Вот много примеров того, как это сделать (некоторые из них уже упоминались), включая полную реализацию чего-то похожего на listagg ():

http://www.oracle -base.com / Статьи / разное / StringAggregationTechniques.php # user_defined_aggregate_function

1 голос
/ 08 марта 2011

Иерархический запрос должен работать.Необходима небольшая дополнительная хитрость, так как вы хотите начать с самого высокого SEQ для каждого PID.

SELECT pid, fulldesc FROM (
  SELECT pid, SYS_CONNECT_BY_PATH( desc, '||' ) fulldesc, seq, minseq FROM (
    SELECT pid, seq, desc,
           MAX(seq) OVER (PARTITION BY pid) maxseq,
           MIN(seq) OVER (PARTITION BY pid) minseq
      FROM tableB
    )
    START WITH seq = maxseq
    CONNECT BY pid = PRIOR pid AND seq = PRIOR seq - 1
  )
  WHERE seq = minseq
  ORDER BY pid
  ;

Редактировать: Один из способов добавить фильтр, как требуется в комментарии:

SELECT pid, fulldesc FROM (
  SELECT pid, SYS_CONNECT_BY_PATH( desc, '||' ) fulldesc, seq, minseq FROM (
    SELECT pid, seq, desc,
           MAX(seq) OVER (PARTITION BY pid) maxseq,
           MIN(seq) OVER (PARTITION BY pid) minseq
      FROM tableB
      WHERE pid IN (SELECT pid FROM tableB WHERE desc='day.')
    )
    START WITH seq = maxseq
    CONNECT BY pid = PRIOR pid AND seq = PRIOR seq - 1
  )
  WHERE seq = minseq
  ORDER BY pid
0 голосов
/ 24 июля 2013

Вы хотите что-то сделать в Oracle, что GROUP_CONCAT делает в MySQL?

Вы можете использовать WM_CONCAT, если он присутствует: http://www.oracle -base.com / Статьи / Разное / строка-агрегацию techniques.php # wm_concat Но это недокументировано, поэтому я бы не стал использовать это на производстве, если бы я был вами.

На 10g пока нет LISTAGG, к сожалению.

Для производственных сред на 10g я бы согласился с ответом Дэйва Косты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...