2017-08-09 4 views
1

J'ai une table avec les colonnes suivantes:Fonction Oracle intégrée pour concaténer plusieurs champs dans un ordre particulier?

Col1|Col2|Col3 
C |B |A 
B |A |C 
A |D |B 

et je voudrais avoir une requête qui concatène les valeurs dans l'ordre croissant dans Col1, Col2 et Col3. E.g. la sortie de la table ci-dessus doit être:

Result 
ABC 
ABC 
ABD 

Oracle fournit-il une fonction intégrée permettant d'agréger plusieurs champs dans un ordre particulier?

+0

Commander La réponse de Gordon. Si votre suivi est ce qu'il faut faire pour 4 colonnes, alors je vous recommande d'obtenir ces valeurs sur _rows_ plutôt que sur les colonnes. Oracle est idéal pour trier les enregistrements, moins pour les colonnes. –

Répondre

2

Non, vous pouvez le faire avec least() et greatest() et case:

select least(col1, col2, col3) || 
     (case when col1 not in (least(col1, col2, col3), greatest(col1, col2, col3)) then col1 
      when col2 not in (least(col1, col2, col3), greatest(col1, col2, col3)) then col2 
      else col3 
     end) || 
     greatest(col1, col2, col3) 
0

Non, mais vous pouvez trouver un moyen de le faire avec une combinaison d'outils existants.

Cette méthode utilise l'opérateur UNION pour placer tous les enregistrements dans une seule colonne en les associant au ROWNUM dont ils proviennent, puis en utilisant la fonction LISTAGG pour concaténer le groupe dans votre jeu de résultats final.

WITH view1 AS (SELECT ROWNUM AS rowid, col1 as col FROM table 
UNION ALL 
SELECT ROWNUM, col2 FROM table 
UNION ALL 
SELECT ROWNUM, col3 FROM table) 
SELECT LISTAGG(col, '') WITHIN GROUP (ORDER BY col) OVER (PARTITION BY rowid) AS Result 
FROM view1 
+0

On dirait que vous et moi sommes venus avec des variations sur le même thème :-) – Kirby

+0

En effet, mais votre réponse est encore une façon différente de le faire. Il y a plusieurs façons de peler un chat, et les grands esprits se ressemblent! – SandPiper

1

Cette requête fera le travail, et il peut être étendu à un nombre arbitraire de colonnes:

Select Listagg(col_val) Within Group (Order By col_val) As sorted_col_values 
From (Select col1, col2, col3, 
      rowid as row_id 
     From t) 
Unpivot(col_val For col in (col1, col2, col3)) 
    Group By row_id; 

L'opérateur Unpivot convertit les trois colonnes de chaque rangée à trois rangées différentes, chacune avec le même identifiant de ligne. La fonction Listagg, en conjonction avec Group By sur row_id, lie les valeurs des colonnes de chaque ligne et les classe par ordre alphabétique.

Je sais ce que vous en pensez, et je suis d'accord: Oracle rock!

+0

Cela me semble correct. – SandPiper