web-dev-qa-db-ja.com

ストアドプロシージャを作成せずに、Oracleで複数の行を1つに連結するにはどうすればよいですか?

ストアドプロシージャを作成せずにOracleで次のことを実現するにはどうすればよいですか?

データセット:

question_id    element_id
1              7
1              8
2              9
3              10
3              11
3              12

望ましい結果:

question_id    element_id
1              7,8
2              9
3              10,11,12
55
Dan Polites

文字列の集計を行う方法は多数ありますが、最も簡単なのはユーザー定義関数です。 関数を必要としない方法のためにこれを試してください。 注として、関数なしで簡単な方法はありません。

これは、カスタム関数なしの最短ルートです:(ROW_NUMBER()およびSYS_CONNECT_BY_PATH関数を使用します)

SELECT questionid,
       LTRIM(MAX(SYS_CONNECT_BY_PATH(elementid,','))
       KEEP (DENSE_RANK LAST ORDER BY curr),',') AS elements
FROM   (SELECT questionid,
               elementid,
               ROW_NUMBER() OVER (PARTITION BY questionid ORDER BY elementid) AS curr,
               ROW_NUMBER() OVER (PARTITION BY questionid ORDER BY elementid) -1 AS prev
        FROM   emp)
GROUP BY questionid
CONNECT BY prev = PRIOR curr AND questionid = PRIOR questionid
START WITH curr = 1;
28
jle

Oracle 11gR2から、 LISTAGG 句がトリックを行うはずです:

SELECT question_id,
       LISTAGG(element_id, ',') WITHIN GROUP (ORDER BY element_id)
FROM YOUR_TABLE
GROUP BY question_id;

結果の文字列が大きすぎる場合(たとえば、VARCHAR2で4000文字以上)に注意してください:バージョン12cR2から ON OVERFLOW TRUNCATE/ERROR を使用してこの問題に対処できます。

101
Emmanuel

簡単:

SELECT question_id, wm_concat(element_id) as elements
FROM   questions
GROUP BY question_id;

10gでペソテスト済み;-)

From http://www.Oracle-base.com/articles/10g/StringAggregationTechniques.php

37
hegemon

このOTNスレッドには、パフォーマンスの比較など、文字列の集約を行ういくつかの方法が含まれています。 http://forums.Oracle.com/forums/message.jspa?messageID=1819487#1819487

2
Rob van Wijk