2017-05-30 73 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