Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment utiliser la fonction Oracle LISTAGG

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; BILL

More 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 connexes
Colonne 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