Функция Oracle LISTAGG е аналитична функция, която ни позволява да конкатенираме низовете за колона_мярка за всяка ГРУПА въз основа на клауза_по_порядък. Това присъства в Oracle от 11gR2
Синтаксисът за функцията LISTAGG в Oracle е
LISTAGG (measure_column [, 'delimiter'])
WITHIN GROUP (order_by_clause) [OVER (query_partition_clause)]
Обяснение на термините
колона_мярка | Колоната или изразът, чиито стойности искате да обедините заедно в резултатния набор. Нулевите стойности в колоната_мярка се игнорират. |
Разделител | По избор. Това е разделителят, който се използва при разделяне на колона_мярка стойности при извеждане на резултатите. |
клауза_по_порядък | Определя реда, в който се връщат конкатенираните стойности |
Нека видим някои случаи и пример за функцията LISTAGG
1) Като агрегатна функция с единичен набор, LISTAGG работи с всички редове и връща единичен изходен ред.
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) Като групов агрегат, функцията работи и връща изходен ред за всяка група, дефинирана от клаузата 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)Като аналитична функция, LISTAGG разделя набора от резултати от заявката на групи въз основа на един или повече изрази в клаузата 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
Добавяне във функция LISTAGG от база данни на Oracle 12cR2
Максималният брой връщани знаци е 4000 байта и ако надвишава , това дава грешка
ORA-01489:резултатът от конкатенацията на низове е твърде дълъг
С Oracle 12cR2 Oracle предостави клауза за съкращаване на препълване, за да се справя грациозно с грешките при препълване
listagg (
measure, ','
[ on overflow (truncate|error) ]
[ text ] [ (with|without) count ]
) within group (order by cols)
Сега можете изрично да кажете дали искате семантика за грешка или отрязване. Кодовете преди 12cR2 работят добре, тъй като това е поведението по подразбиране
Сега да предположим, че не искате да връщате грешка, когато тя пресече 4k байта, след което при препълване съкращава е решението.
select table_name,
listagg(index_name, ',' on overflow truncate) within group (order by index_name) inds
from user_indexes
group by table_name;
В случай на съкращаване, Oracle ще съкрати обратно до следващата пълна стойност, в който момент можете да контролирате как да кажете на потребителя, че списъкът е бил съкратен. По подразбиране ние добавяме три точки „...“ към низа като индикатор, че е настъпило съкращаване. Можете да промените „....“, ако желаете, можете да го замените
Ако искате да замените „...“ с „още“, „екстра“ или „щракнете за повече“ хипервръзка, просто предоставете новия си низ!
select table_name,
listagg(index_name, ',' on overflow truncate
'|||'
) within group (order by index_name) inds
from user_indexes
group by table_name;
По подразбиране truncate показва броя на липсващите стойности Ако не искате да показвате броя, тогава използвайте без броене
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 (10g, 9i , 11gR1)
Ако не използвате 11g Release 2 или по-нова, но изпълнявате версия на базата данни, в която присъства функцията WM_CONCAT, тогава това е решение без усилия, тъй като извършва агрегирането вместо вас. Това всъщност е пример за дефинирана от потребителя обобщена функция, описана по-долу, но Oracle свърши цялата работа вместо вас.
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
Това може да се постигне и чрез дефинирана от потребителя функция. Бих препоръчал да проверите връзката на asktom по-долу. Това трябва да се прочете
Алтернативна опция Listagg
Надявам се, че съдържанието на тази публикация за Oracle LISTAGG Function ви харесва
Сродни статииКолона за автоматично увеличение – последователност като стойност по подразбиране в Oracle и mysql
Oracle се присъединява
Sql набор оператори
Как да използвате URL адрес на google translate в Oracle plsql
Едноредови функции в sql
функция за дата в oracle