sql >> Databasteknik >  >> RDS >> Oracle

Hur man använder Oracle LISTAGG-funktionen

Oracle LISTAGG-funktion är en analytisk funktion som låter oss sammanfoga strängarna för måttkolumn för varje GROUP baserat på order_by_clausen. Detta finns i Oracle från 11gR2

Syntaxen för LISTAGG-funktionen i Oracle är

LISTAGG (measure_column [, 'delimiter'])
WITHIN GROUP (order_by_clause) [OVER (query_partition_clause)]

Förklaring av termer

måttkolumn Kolumnen eller uttrycket vars värden du vill sammanfoga i resultatuppsättningen. Nullvärden i mätkolumnen ignoreras.
Avgränsare Valfritt. Det är avgränsaren som ska användas när du separerar måttkolumnen värden när resultaten matas ut.
order_by_clause Det bestämmer i vilken ordning de sammanlänkade värdena returneras

Låt oss se några fall och exempel på LISTAGG-funktionen

1) Som en enstaka aggregatfunktion fungerar LISTAGG på alla rader och returnerar en enda utdatarad.

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) Som ett gruppuppsättningsaggregat arbetar funktionen på och returnerar en utdatarad för varje grupp som definieras av GROUP BY-satsen.

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)Som en analytisk funktion partitionerar LISTAGG frågeresultatuppsättningen i grupper baserat på ett eller flera uttryck i 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

Tillägg i LISTAGG-funktion från Oracle-databasen 12cR2

Det maximala antalet tecken som returneras är 4000 byte och om det överstiger , ger det felet

ORA-01489:resultatet av strängsammansättningen är för lång

Med Oracle 12cR2 har Oracle tillhandahållit en klausul om bräddavkortning för att hantera spillfel på ett elegant sätt

listagg (
measure, ','
[ on overflow (truncate|error) ]
[ text ] [ (with|without) count ]
) within group (order by cols)

Nu kan du uttryckligen säga om du vill ha fel- eller trunkeringssemantik. Pre 12cR2-koderna fungerar bra eftersom det är standardbeteendet

Anta nu att du inte vill returnera fel när det passerar 4k byte, sedan vid överflöde trunkera är lösningen.

select table_name,
listagg(index_name, ',' on overflow truncate) within group (order by index_name) inds
from user_indexes
group by table_name;

Om trunkering inträffar kommer Oracle  att trunkeras tillbaka till nästa fullständiga värde. Då kan du styra hur du berättar för användaren att listan har trunkerats. Som standard lägger vi till tre punkter "..." till strängen som indikator på att trunkering har inträffat. Du kan ändra '...' om du vill kan du åsidosätta det

Om du vill ersätta "..." med "mer", "extra" eller en "klicka för mer" hyperlänk, ange bara din nya sträng!

select table_name,
listagg(index_name, ',' on overflow truncate
'|||'
) within group (order by index_name) inds
from user_indexes
group by table_name;

Som standard visar trunkering antalet saknade värden Om du inte vill visa antalet, använd sedan utan räkning

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;

Pre 11GR2-lösning (10g, 9i, 11gR1)

Om du inte kör 11g Release 2 eller högre, men kör en version av databasen där funktionen WM_CONCAT finns, är det en lösning utan ansträngning eftersom den utför aggregeringen åt dig. Det är faktiskt ett exempel på en användardefinierad aggregerad funktion som beskrivs nedan, men Oracle har gjort allt arbete åt dig.

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

Detta kan också uppnås genom användardefinierad funktion. Jag skulle rekommendera att kolla asktom-länken nedan. Detta måste läsas

Listagg alternativt alternativ

Jag hoppas att du gillar innehållet i det här inlägget på Oracle LISTAGG Function

Relaterade artiklar
Automatisk ökningskolumn – Sekvens som standardvärde i Oracle och mysql
Oracle Joins
Sql Set Operators
Hur man använder google translate URL i Oracle plsql
Enradsfunktioner i sql
datumfunktion i Oracle

  1. Hur man beräknar glidande medelvärde i rödförskjutning

  2. Hur man löser felet `prisma/klienten har inte initierats ännu` på Vercel

  3. Schemadefinitioner av DBMS

  4. Online kontra offline säkerhetskopiering