Oracle
 sql >> база данни >  >> RDS >> Oracle

Как да използвате функцията Oracle LISTAGG

Функция 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; 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)Като аналитична функция, 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

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Форматът на датата по подразбиране на Oracle е ГГГГ-ММ-ДД, ЗАЩО?

  2. Изявление на Oracle

  3. Създаване на глобална временна таблица в Oracle

  4. Фина настройка на Oracle DG40DBC

  5. Как да използвате URL адрес на Google Translate в Oracle plsql