Comment puis-je atteindre les objectifs suivants dans Oracle sans créer de procédure stockée?
Ensemble de données:
question_id element_id
1 7
1 8
2 9
3 10
3 11
3 12
Résultat désiré:
question_id element_id
1 7,8
2 9
3 10,11,12
Il y a beaucoup de façons de faire l'agrégation de chaînes, mais le plus simple est une fonction définie par l'utilisateur. Essayez ceci pour un moyen qui ne nécessite pas de fonction. En note, il n'y a pas de moyen simple sans la fonction.
C'est la route la plus courte sans fonction personnalisée: (elle utilise les fonctions ROW_NUMBER () et 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;
Dans Oracle 11gR2, la clause LISTAGG devrait faire l'affaire:
SELECT question_id,
LISTAGG(element_id, ',') WITHIN GROUP (ORDER BY element_id)
FROM YOUR_TABLE
GROUP BY question_id;
Faites attention si la chaîne résultante est trop grosse (plus de 4000 caractères pour un VARCHAR2, par exemple): à partir de la version 12cR2, nous pouvons utiliser ON OVERFLOW TRUNCATE/ERROR pour résoudre ce problème.
Facile:
SELECT question_id, wm_concat(element_id) as elements
FROM questions
GROUP BY question_id;
Pesonally testé sur 10g ;-)
De http://www.Oracle-base.com/articles/10g/StringAggregationTechniques.php
Ce fil OTN contient plusieurs manières de faire une agrégation de chaînes, y compris une comparaison de performances: http://forums.Oracle.com/forums/message.jspa?messageID=1819487#1819487