Avant Oracle 11.2, j'utilisais une fonction d'agrégation personnalisée pour concaténer une colonne dans une ligne. 11.2 Ajout de la LISTAGG
fonction, j'essaie donc de l'utiliser à la place. Mon problème est que je dois éliminer les doublons dans les résultats et ne semble pas pouvoir le faire.
Voici un exemple.
CREATE TABLE ListAggTest AS (
SELECT rownum Num1, DECODE(rownum,1,'2',to_char(rownum)) Num2 FROM dual
CONNECT BY rownum<=6
);
SELECT * FROM ListAggTest;
NUM1 NUM2
---------- ---------------------
1 2
2 2 << Duplicate 2
3 3
4 4
5 5
6 6
Ce que je veux voir, c'est ceci:
NUM1 NUM2S
---------- --------------------
1 2-3-4-5-6
2 2-3-4-5-6
3 2-3-4-5-6
4 2-3-4-5-6
5 2-3-4-5-6
6 2-3-4-5-6
Voici une listagg
version qui est proche, mais n'élimine pas les doublons.
SELECT Num1, listagg(Num2,'-') WITHIN GROUP (ORDER BY NULL) OVER () Num2s
FROM ListAggTest;
J'ai une solution, mais c'est pire que de continuer à utiliser la fonction d'agrégat personnalisé.
oracle
oracle-11g-r2
aggregate
Leigh Riffel
la source
la source
order by null
êtreorder by Num2
ou que je reçois confus?LISTAGG
continue d'être en deçà de Tom KyteSTRAGG
, avec lequel il est aussi facile queSTRAGG(DISTINCT ...)
Réponses:
Vous pouvez utiliser des expressions régulières et
regexp_replace
supprimer les doublons après la concaténation aveclistagg
:Cela pourrait être plus ordonné si la saveur regex d'Oracle prenait en charge les groupes avec ou sans capture, mais ce n'est pas le cas .
Cependant, cette solution évite d'analyser la source plus d'une fois.
DBFiddle ici
la source
ORDER BY Num2
accomplit n'est-ce pas (voir ici ). Ou essayez-vous simplement de souligner que vous avez besoin de ORDER BY pour que cela fonctionne?Autant que je sache, avec la spécification de langue actuellement disponible, il s’agit de la solution la plus courte pour obtenir ce que vous voulez si elle doit être exécutée
listagg
.Quelle était votre solution qui était pire que la solution d'agrégat personnalisé ?
la source
regexp
solution.Créez une fonction d'agrégat personnalisée pour le faire.
la source
Bien que ce soit un ancien message avec une réponse acceptée, je pense que la fonction analytique de LAG () fonctionne bien dans ce cas et est remarquable:
Voici le code proposé:
Les résultats ci-dessous semblent correspondre à ce que souhaite le PO:
la source
Voici ma solution au problème qui, à mon avis, n’est pas aussi agréable que d’utiliser notre fonction d’agrégat personnalisée qui existe déjà.
la source
Utilisez WMSYS.WM_Concat à la place.
Remarque: cette fonction est non documentée et non prise en charge. Voir https://forums.oracle.com/forums/message.jspa?messageID=4372641#4372641 .
la source
wm_concat
(même si vous affirmez que lewm_concat
problème n'est pas lui-même à l'origine du problème), ils auraient des raisons de refuser de fournir une aide, car elle est non documentée et non prise en charge. Ce n'est pas le cas si vous utilisez un agrégat personnalisé ou tout autre fonctionnalité prise en charge.Vous pouvez également utiliser une instruction collect, puis écrire une fonction pl / sql personnalisée qui convertit la collection en chaîne.
Vous pouvez utiliser
distinct
etorder by
dans unecollect
clause, mais si vous ledistinct
combinez, cela ne fonctionnera pas à partir du 11.2.0.2 :(La solution de rechange pourrait être une sous-sélection:
la source
J'ai créé cette solution avant de rencontrer ListAgg, mais il existe encore des cas, tels que ce problème de valeur en double, alors cet outil est utile. La version ci-dessous a 4 arguments pour vous permettre de contrôler les résultats.
Explication CLOBlist prend le constructeur CLOBlistParam en tant que paramètre. CLOBlistParam a 4 arguments
Exemple d'utilisation
Lien vers Gist est ci-dessous.
https://gist.github.com/peter-genesys/d203bfb3d88d5a5664a86ea6ee34eeca] 1
la source
Je sais que c'est quelque temps après la publication initiale, mais c'était la première fois que je trouvais une réponse au même problème après Google et que quelqu'un qui aurait atterri ici serait heureux de trouver une réponse succincte qui ne repose pas sur des requêtes trop compliquées. ou regexes.
Cela vous donnera le résultat souhaité:
la source
Mon idée est d'implémenter une fonction stockée comme ceci:
Désolé, mais dans certains cas (pour un très gros lot), Oracle pourrait renvoyer cette erreur:
mais je pense que c'est un bon point de départ;)
la source
LISTAGG
fonction personnalisée ; ils essayaient explicitement de voir s'ils pouvaient trouver un moyen efficace de le faire en utilisant laLISTAGG
fonction intégrée disponible à partir de la version 11.2.Essaye celui-là:
Le problème avec d'autres solutions possibles est qu'il n'y a pas de corrélation entre les résultats des colonnes 1 et 2. Pour contourner ce problème, la requête interne crée cette corrélation puis supprime les doublons de cet ensemble de résultats. Lorsque vous faites le listagg, le résultat est déjà propre. le problème tenait davantage à obtenir les données dans un format utilisable.
la source
SQL a été conçu comme un langage simple, très proche de l'anglais. Alors, pourquoi ne l'écrivez-vous pas en anglais?
la source
la source
SELECT Num1, ( SELECT LISTAGG(Num2) WITHIN GROUP (ORDER BY Num2) FROM (SELECT distinct Num2 FROM listAggTest) ) Num2 FROM ListAggTest;
La solution la plus efficace est la sélection interne avec GROUP BY, car DISTINCT et les expressions régulières sont lents.
Cette solution est assez simple - vous obtenez d’abord toutes les combinaisons uniques de num1 et num2 (SELECT interne), puis la chaîne de tous les num2 regroupée par num1.
la source
SELECT * FROM ListAggTest;
.