2017-05-30 77 views
1

我试图限制我的SQL查询中使用LISTAGG只将前3行分组到单个列中的一列。在Oracle中限制LISTAGG结果

例如:

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连接的数据,我不完全知道如何限制结果发送到前3条记录。

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

这可能与LISTAGG?任何帮助将不胜感激。由于

回答

1

您可以通过枚举行和使用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表格代表无序集合;除非列指定了排序,否则不存在“前三个”或“后三个”。

1

在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