Ограничение результатов LISTAGG в Oracle

Я пытаюсь ограничить один из моих столбцов в моем SQL-запросе, который использует LISTAGG, чтобы сгруппировать только первые 3 строки в один столбец.

Например:

Table
-----
Name   Orders
---------------
Joe    Joe_Order1
Joe    Joe_Order2
Joe    Joe_Order3
Joe    Joe_Order4
Joe    Joe_Order5
Joe    Joe_Order6
Mark   Mark_Order1
Mark   Mark_Order2
Mark   Mark_Order3
Mark   Mark_Order4

Пусть он вернет следующее...

Name   Recent_Orders
-----------------------------
Joe    Joe_Order1, Joe_Order2, Joe_Order3
Mark   Mark_Order1, Mark_Order2, Mark_Order3

Однако я могу объединить данные с помощью listagg, но я не совсем уверен, как ограничить результаты первыми тремя записями.

SELECT NAME, LISTAGG(Orders, ', ') within group(order by Orders)
  as Recent_Orders
FROM
  Order_table
GROUP BY
  NAME

Возможно ли это с LISTAGG? Любая помощь будет принята с благодарностью. Спасибо


person msleone    schedule 30.05.2017    source источник


Ответы (2)


Примените row_number в CTE, затем примените ограничение в предложении WHERE.

with CTE as
(
select row_number() over(partition by NAME order by Orders) as rn,
       a1.*
from Order_Table a1
)
SELECT NAME, LISTAGG(Orders, ', ') within group(order by Orders)
  as Recent_Orders
FROM
  CTE
WHERE 
  rn <=3
GROUP BY
  NAME
person JohnHC    schedule 30.05.2017

Вы можете сделать это, перечислив строки и используя case:

SELECT NAME,
       LISTAGG(CASE WHEN seqnum <= 3 THEN Orders END, ', ') WITHIN GROUP (ORDER BY Orders) as Recent_Orders
FROM (SELECT o.*, ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY ?? DESC) as seqnum
      FROM Order_table o
     ) o
GROUP BY NAME;

По умолчанию LISTAGG() игнорирует значения NULL, так что это делает то, что вы хотите.

?? — это столбец для указания порядка. Таблицы SQL представляют неупорядоченные наборы; нет «первых трех» или «последних трех», если столбец не указывает порядок.

person Gordon Linoff    schedule 30.05.2017