sql >> Databáze >  >> RDS >> Oracle

Jak používat funkci Oracle LISTAGG

Funkce Oracle LISTAGG je analytická funkce, která nám umožňuje zřetězit řetězce pro sloupec opatření pro každou GROUP na základě order_by_clause. Toto je přítomno v Oracle od 11gR2

Syntaxe funkce LISTAGG v Oracle je

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

Vysvětlení pojmů

measure_column Sloupec nebo výraz, jehož hodnoty chcete zřetězit dohromady ve výsledné sadě. Hodnoty Null ve sloupci opatření jsou ignorovány.
Oddělovač Volitelné. Je to oddělovač, který se použije při oddělování sloupec_měřit hodnoty při výstupu výsledků.
order_by_clause Určuje pořadí, ve kterém jsou vráceny zřetězené hodnoty

Podívejme se na některé případy a příklad na funkci LISTAGG

1) Jako agregační funkce s jednou sadou funguje LISTAGG na všech řádcích a vrací jeden výstupní řádek.

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) Jako agregační skupina skupin funguje funkce a vrací výstupní řádek pro každou skupinu definovanou klauzuli 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) Jako analytická funkce LISTAGG rozděluje sadu výsledků dotazu do skupin na základě jednoho nebo více výrazů v 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

Přidání funkce LISTAGG z databáze Oracle 12cR2

Maximální počet vrácených znaků je 4000 bajtů a pokud překročí , zobrazí chybu

ORA-01489:výsledek zřetězení řetězců je příliš dlouhý

S Oracle 12cR2 poskytl Oracle klauzuli o zkrácení přetečení, aby se s chybami přetečení vyrovnalo elegantně

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

Nyní můžete explicitně říci, zda chcete sémantiku chyby nebo zkrácení. Kódy před 12cR2 fungují dobře, protože to je výchozí chování

Nyní předpokládejme, že nechcete vrátit chybu, když překročí 4 kB, a poté při přetečení zkrátit je řešením.

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

V případě, že dojde ke zkrácení, Oracle se zkrátí zpět na další plnou hodnotu, kdy můžete ovládat, jak uživateli sdělíte, že byl seznam zkrácen. Ve výchozím nastavení připojujeme k řetězci tři tečky „…“ jako indikátor, že došlo ke zkrácení. Pokud chcete, můžete změnit „….“, můžete to přepsat

Pokud chcete nahradit „…“ hypertextovým odkazem „více“, „extra“ nebo „kliknutím zobrazíte další“, stačí zadat nový řetězec!

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

Ve výchozím nastavení zkrácení zobrazuje počet chybějících hodnot. Pokud nechcete zobrazit počet, použijte bez počtu

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

Pokud nepoužíváte 11g Release 2 nebo vyšší, ale používáte verzi databáze, kde je přítomna funkce WM_CONCAT, pak je to řešení s nulovou námahou, protože provádí agregaci za vás. Ve skutečnosti je to příklad uživatelsky definované agregační funkce popsané níže, ale Oracle udělal veškerou práci za vás.

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

Toho lze také dosáhnout pomocí funkce definované uživatelem. Doporučil bych zkontrolovat níže uvedený odkaz asktom. Toto si musíte přečíst

Alternativní možnost Listagg

Doufám, že se vám obsah tohoto příspěvku na Oracle LISTAGG Function bude líbit

Související články
Sloupec automatického přírůstku – sekvence jako výchozí hodnota v Oracle a mysql
Připojení Oracle
Operátoři sady SQL
Jak používat adresu URL překladače Google v Oracle plsql
Jednořádkové funkce v sql
funkce data v oracle

  1. nhibernate, volání funkce v Oracle, která vrací sys refcursor

  2. Mohu vytvořit pohled s parametrem v MySQL?

  3. Jak nastavit primární klíč automatického zvýšení v PostgreSQL?

  4. Výkon aplikací založených na PostgreSQL:latence a skryté zpoždění