在 Oracle 中限制 LISTAGG 结果

msl*_*one 6 sql oracle listagg

我试图限制我的 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
Run Code Online (Sandbox Code Playgroud)

让它返回以下...

Name   Recent_Orders
-----------------------------
Joe    Joe_Order1, Joe_Order2, Joe_Order3
Mark   Mark_Order1, Mark_Order2, Mark_Order3
Run Code Online (Sandbox Code Playgroud)

我可以使用 listagg 连接数据,但是我不完全确定如何将结果限制为前 3 条记录。

SELECT NAME, LISTAGG(Orders, ', ') within group(order by Orders)
  as Recent_Orders
FROM
  Order_table
GROUP BY
  NAME
Run Code Online (Sandbox Code Playgroud)

这可以用 LISTAGG 实现吗?任何帮助将不胜感激。谢谢

Joh*_*nHC 5

在 CTE 中应用 row_number,然后在 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
Run Code Online (Sandbox Code Playgroud)


Gor*_*off 4

您可以通过枚举行并使用以下命令来完成此操作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;
Run Code Online (Sandbox Code Playgroud)

默认情况下,LISTAGG()忽略NULL值,因此这可以满足您的要求。

??是用于指定顺序的列。SQL表代表无序集合;除非列指定顺序,否则没有“前三个”或“后三个”。