J'ai une table qui ressemble à ceci:
A 1
A 2
B 1
B 2
Et je veux produire un jeu de résultats qui ressemble à ceci:
A 1 2
B 1 2
Existe-t-il une instruction SQL qui fera cela? J'utilise Oracle.
Questions connexes:
Cela dépend de la version d'Oracle que vous utilisez. S'il prend en charge la fonction wm_concat (), vous pouvez simplement faire quelque chose comme ceci:
SELECT field1, wm_concat(field2) FROM YourTable GROUP BY field2;
wm_concat () fonctionne essentiellement comme group_concat () dans MySQL. Cela peut ne pas être documenté, alors lancez ye olde sqlplus et voyez s'il est là.
S'il n'est pas là, alors vous voudrez implémenter vous-même quelque chose d'équivalent. Vous pouvez trouver des instructions sur la façon de procéder dans la page d'agrégation de chaînes sur Oracle-base.com.
Sujet assez ancien, mais cela pourrait aider les autres depuis qu'Oracle s'est amélioré entre-temps.
La fonction LISTAGG est ce que vous recherchez (en 11g au moins)
Dans Oracle 10g+
:
SELECT *
FROM (
SELECT *
FROM mytable
MODEL
PARTITION BY
(grouper)
DIMENSION BY
(ROW_NUMBER() OVER (PARTITION BY grouper ORDER BY id) AS rn)
MEASURES
(val, val AS group_concat, 0 AS mark)
RULES SEQUENTIAL ORDER (
group_concat[rn > 1] ORDER BY rn = group_concat[CV() - 1] || ', ' || val[CV()],
mark[ANY] ORDER BY rn = PRESENTV(mark[CV() + 1], 0, 1)
)
)
WHERE mark = 1
ORDER BY
grouper
Voir cet article dans mon blog pour des explications:
Essayez quelque chose comme:
SELECT
field1,
RTRIM(REPLACE(REPLACE(XMLAgg(XMLElement("x", field2) ORDER BY field2), '<x>'), '</x>', ' ')) AS field2s
FROM yourTable
GROUP BY field1
Librement inspiré par une réponse trouvée dans ce forum Oracle .
EDIT: cette solution a prouvé très ressources intensives avec des demandes impliquant quelque chose comme 105 Lignes. J'ai fini par remplacer cela par des fonctions d'agrégation personnalisées comme suggéré par John .
Si vous avez 10g, vous devez passer par la fonction ci-dessous:
CREATE OR REPLACE FUNCTION get_separated_value (input_val in number)
RETURN VARCHAR2
IS
return_text VARCHAR2(10000) := NULL;
BEGIN
FOR x IN (SELECT col2 FROM table_name WHERE col1 = input_val) LOOP
return_text := return_text || ' ' || x.col2 ;
END LOOP;
RETURN return_text;
END;
/
Ainsi, vous pouvez faire comme:
select col1, get_separated_value(col1) from table_name
Si vous avez Oracle 11g, vous pouvez utiliser listagg :
SELECT
age,
LISTAGG(name, ' ') WITHIN GROUP (ORDER BY name) "names"
FROM table_x
GROUP BY age
Fonctions d'agrégation définies par l'utilisateur: http://www.adp-gmbh.ch/ora/sql/user_def_agg.html
Copiez/collez et utilisez-le. Fonctionne sur 9i.
SELECT a , COLLECT(b) FROM foo GROUP BY a
très utile lorsqu'il est utilisé dans pl/sql - peut être casté dans une collection définie par l'utilisateur.