ストアドプロシージャを作成せずに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
文字列の集計を行う方法は多数ありますが、最も簡単なのはユーザー定義関数です。 関数を必要としない方法のためにこれを試してください。 注として、関数なしで簡単な方法はありません。
これは、カスタム関数なしの最短ルートです:(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;
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 を使用してこの問題に対処できます。
簡単:
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
このOTNスレッドには、パフォーマンスの比較など、文字列の集約を行ういくつかの方法が含まれています。 http://forums.Oracle.com/forums/message.jspa?messageID=1819487#1819487