2009-07-02 5 views

Répondre

25

Il y a plusieurs façons de faire l'agrégation de chaîne, mais le plus simple est une fonction définie par l'utilisateur. Try this for a way that does not require a function. Comme une note, il n'y a pas de moyen simple sans la fonction.

Ceci est le plus court chemin sans une fonction personnalisée: (il utilise le ROW_NUMBER() et les fonctions de 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; 
+0

fonctionne très bien! ROW_NUMBER() est ce qui me manquait pour que sys_connect_by_path fonctionne pour moi. –

+1

Notez que lorsque cette technique est appliquée pour concaténer un champ dont la valeur peut contenir le séparateur, l'erreur suivante est levée: 'ORA-30004: en utilisant la fonction SYS_CONNECT_BY_PATH, ne peut pas avoir de séparateur comme partie de la valeur de la colonne. la valeur concaténée arrive à dépasser la longueur maximale de 4000 octets, vous obtiendrez l'erreur: 'ORA-01489: le résultat de la concaténation de chaîne est trop long .' – Somu

32

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

+3

Notez cependant que wm_concat est une fonction non documentée. Vous devriez donc réfléchir à deux fois avant de l'utiliser dans le code de production. –

+0

Très cool. Fonctionne pour moi aussi, mais je dois m'assurer que cette fonction est disponible dans notre environnement de production. –

+2

Je reçois Erreur -> ORA-00904 WM_CONCAT: Identifiant invalide –

69

d'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; 
+3

En note, nous pouvons connaître la version de la base de données en interrogeant la table 'v $ version' ou' product_component_version'. 11.2 indique 11gR2. – Somu

+0

en tout cas il m'a aidé – Almas

+0

En l'utilisant depuis longtemps et c'est aussi simple que possible. – elrado

Questions connexes