sql >> Database >  >> RDS >> Oracle

Hoe de Oracle LISTAGG-functie te gebruiken?

Oracle LISTAGG-functie is een analytische functie waarmee we de strings voor meetkolom voor elke GROUP kunnen samenvoegen op basis van de order_by_clause. Dit is aanwezig in Oracle vanaf 11gR2

De syntaxis voor de LISTAGG-functie in Oracle is

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

Uitleg van termen

measure_column De kolom of expressie waarvan u de waarden wilt samenvoegen in de resultatenset. Null-waarden in de meetkolom worden genegeerd.
Scheidingsteken Optioneel. Het is het scheidingsteken dat moet worden gebruikt bij het scheiden van de measure_column waarden bij het uitvoeren van de resultaten.
order_by_clause Het bepaalt de volgorde waarin de aaneengeschakelde waarden worden geretourneerd

Laten we enkele gevallen en voorbeelden van de LISTAGG-functie bekijken

1) Als een enkelvoudige aggregatiefunctie werkt LISTAGG op alle rijen en retourneert een enkele uitvoerrij.

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) Als een groepset-aggregaat werkt de functie op en retourneert een uitvoerrij voor elke groep die is gedefinieerd door de GROUP BY-clausule.

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)Als analytische functie verdeelt LISTAGG de set met queryresultaten in groepen op basis van een of meer expressies in de 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

Toevoeging in LISTAGG-functie uit Oracle-database 12cR2

Het maximale aantal tekens dat wordt geretourneerd is 4000 bytes en als het groter is, geeft het de fout

ORA-01489:resultaat van tekenreeksaaneenschakeling is te lang

Met Oracle 12cR2 heeft Oracle een clausule over overflow truncate geleverd om overflowfouten gracieus af te handelen

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

U kunt nu expliciet aangeven of u fout- of afkapsemantiek wilt. De codes van vóór 12cR2 werken prima, want dat is het standaardgedrag

Stel nu dat u geen fout wilt retourneren wanneer deze 4k bytes overschrijdt, en bij overloop afkappen is de oplossing.

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

In het geval dat er wordt afgekapt, wordt Oracle afgekapt tot de volgende volledige waarde, waarna u kunt bepalen hoe u de gebruiker vertelt dat de lijst is afgekapt. Standaard voegen we drie puntjes '...' toe aan de tekenreeks als indicator dat er is afgekapt. U kunt de '...' wijzigen als u wilt, u kunt dat overschrijven

Als u "..." wilt vervangen door "meer", "extra" of een "klik voor meer" hyperlink, geef dan gewoon uw nieuwe tekenreeks op!

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

Standaard toont truncate het aantal ontbrekende waarden. Als u het aantal niet wilt tonen, gebruik dan zonder telling

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-oplossing (10g, 9i, 11gR1)

Als u 11g Release 2 of hoger niet gebruikt, maar een versie van de database gebruikt waarin de WM_CONCAT-functie aanwezig is, dan is het een eenvoudige oplossing omdat het de aggregatie voor u uitvoert. Het is eigenlijk een voorbeeld van een door de gebruiker gedefinieerde aggregatiefunctie die hieronder wordt beschreven, maar Oracle heeft al het werk voor u gedaan.

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

Dit kan ook worden bereikt via een door de gebruiker gedefinieerde functie. Ik zou aanraden om de onderstaande asktom-link te bekijken. Dit moet je lezen

Listagg alternatieve optie

Ik hoop dat je de inhoud van dit bericht op Oracle LISTAGG Function . leuk vindt

Verwante artikelen
Kolom automatisch verhogen – Volgorde als standaardwaarde in Oracle en mysql
Oracle voegt zich bij
Sql Set-operators
Hoe Google Translate-URL te gebruiken in Oracle plsql
Functies met één rij in sql
datumfunctie in orakel

  1. Crystal Reports versus Microsoft SQL Server Reporting Services

  2. 3 manieren om rijen met kleine letters te vinden in SQLite

  3. Wat is het verschil tussen expliciete en impliciete cursors in Oracle?

  4. Early bird inschrijvingen geopend voor PGDay.IT 2011