Fonction Oracle LISTAGG est une fonction analytique qui nous permet de concaténer les chaînes de measure_column pour chaque GROUP en fonction de la clause order_by. Ceci est présent dans Oracle à partir de 11gR2
La syntaxe de la fonction LISTAGG dans Oracle est
LISTAGG (measure_column [, 'delimiter'])
WITHIN GROUP (order_by_clause) [OVER (query_partition_clause)]
Explication des termes
measure_column | La colonne ou l'expression dont vous souhaitez concaténer les valeurs dans le jeu de résultats. Les valeurs nulles dans measure_column sont ignorées. |
Séparateur | Facultatif. Il s'agit du délimiteur à utiliser lors de la séparation de measure_column valeurs lors de la sortie des résultats. |
order_by_clause | Il détermine l'ordre dans lequel les valeurs concaténées sont renvoyées |
Voyons quelques cas et exemple sur la fonction LISTAGG
1) En tant que fonction d'agrégation à un seul ensemble, LISTAGG fonctionne sur toutes les lignes et renvoie une seule ligne de sortie.
SELECT LISTAGG(first_name, '; ')
WITHIN GROUP (ORDER BY hire_date, last_name) "Employee_list",
MIN(hire_date) "Earliest"
FROM emp
WHERE dept_no = 30;Employee_list Earliest
------------------------------------------------------------ ---------
TOM; BOB; BILL 17-JUN-18
2) En tant qu'agrégat d'ensemble de groupes, la fonction opère sur et renvoie une ligne de sortie pour chaque groupe défini par la clause GROUP BY.
COLUMN employees FORMAT A50
SELECT deptno, LISTAGG(ename, ';') WITHIN GROUP (ORDER BY ename) AS employees
FROM emp
GROUP BY deptno;
DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 JOSHUA,KING,MILLER
20 AJAY,FANES,SCOTT,SMITH
30 TOM; BOB; BILLMore Example
select table_name,
listagg(index_name, ',') within group (order by index_name) all_inds
from user_indexes
group by table_name;
3) En tant que fonction analytique, LISTAGG partitionne le jeu de résultats de la requête en groupes en fonction d'une ou plusieurs expressions dans query_partition_clause.
SQL> SELECT deptno
, ename
, hiredate
, LISTAGG(ename, ',')
WITHIN GROUP (ORDER BY hiredate)
OVER (PARTITION BY deptno) AS employees
FROM emp order by deptno;DEPTNO ENAME HIREDATE EMPLOYEES
---------- ---------- ----------- -------------------------------------
10 JOSHUA 09/06/2018 JOSHUA,KING,MILLER
10 KING 17/11/2018 JOSHUA,KING,MILLER
10 MILLER 23/01/2018 JOSHUA,KING,MILLER
20 AJAY 17/12/2018 AJAY,FANES,SCOTT,SMITH
20 FANES 02/04/2018 AJAY,FANES,SCOTT,SMITH
20 SCOTT 19/04/2018 AJAY,FANES,SCOTT,SMITH
20 SMITH 23/05/2018 AJAY,FANES,SCOTT,SMITH
30 TOM 20/02/2018 TOM; BOB; BILL
30 BOB 22/02/2018 TOM; BOB; BILL
30 BILL 01/05/2018 TOM; BOB; BILL
Ajout dans la fonction LISTAGG de la base de données Oracle 12cR2
Le nombre maximum de caractères retournés est de 4000 octets et s'il dépasse, cela donne l'erreur
ORA-01489 :le résultat de la concaténation de chaînes est trop long
Avec Oracle 12cR2, Oracle a fourni une clause sur la troncature de débordement pour gérer les erreurs de débordement avec élégance
listagg (
measure, ','
[ on overflow (truncate|error) ]
[ text ] [ (with|without) count ]
) within group (order by cols)
Vous pouvez désormais indiquer explicitement si vous souhaitez une sémantique d'erreur ou de troncature. Les codes antérieurs à 12cR2 fonctionnent correctement, car c'est le comportement par défaut
Supposons maintenant que vous ne vouliez pas renvoyer d'erreur lorsqu'il franchit 4 000 octets, puis en cas de débordement tronqué est la solution.
select table_name,
listagg(index_name, ',' on overflow truncate) within group (order by index_name) inds
from user_indexes
group by table_name;
En cas de troncature, Oracle reviendra à la valeur complète suivante, à partir de laquelle vous pourrez contrôler la manière dont vous informez l'utilisateur que la liste a été tronquée. Par défaut, nous ajoutons trois points "..." à la chaîne pour indiquer qu'une troncature a eu lieu. Vous pouvez modifier le "…." si vous le souhaitez, vous pouvez remplacer cela
Si vous souhaitez remplacer « ... » par « plus », « extra » ou un lien hypertexte « cliquez pour en savoir plus », fournissez simplement votre nouvelle chaîne !
select table_name,
listagg(index_name, ',' on overflow truncate
'|||'
) within group (order by index_name) inds
from user_indexes
group by table_name;
Par défaut, tronquer affiche le nombre de valeurs manquantes Si vous ne voulez pas afficher le nombre, utilisez-le sans compter
select table_name,
listagg(index_name, ',' on overflow truncate '....' without count) within group (order by index_name) inds
from user_indexes
group by table_name;
Solution pré 11GR2 (10g, 9i , 11gR1)
Si vous n'exécutez pas 11g Release 2 ou une version ultérieure, mais que vous exécutez une version de la base de données dans laquelle la fonction WM_CONCAT est présente, il s'agit d'une solution sans effort car elle effectue l'agrégation pour vous. Il s'agit en fait d'un exemple de fonction d'agrégation définie par l'utilisateur décrite ci-dessous, mais Oracle a fait tout le travail pour vous.
COLUMN employees FORMAT A50
SELECT deptno, wm_concat(ename) AS employees
FROM emp
GROUP BY deptno;
EPTNO EMPLOYEES
---------- --------------------------------------------------
10 JOSHUA,KING,MILLER
20 AJAY,FANES,SCOTT,SMITH
30 TOM; BOB; BILL
Cela peut également être réalisé via une fonction définie par l'utilisateur. Je recommanderais de vérifier le lien asktom ci-dessous. Ceci est à lire
Option alternative Listagg
J'espère que vous aimez le contenu de cet article sur la fonction Oracle LISTAGG
Articles connexesColonne d'incrémentation automatique – Séquence comme valeur par défaut dans Oracle et mysql
Oracle Joins
Opérateurs d'ensemble SQL
Comment utiliser Google Translate URL dans Oracle plsql
Fonctions à une seule ligne dans sql
fonction date dans oracle