如何 select 每组的最后 N 行 - Oracle 11g

How to select bottom N rows from each group - Oracle 11g

我有一个table如下:

+-----------------+----------+-------------+-------------+
| QCD_OUTLET_CODE | QCD_YEAR | QCD_QUARTER | QCD_CREDITS |
+-----------------+----------+-------------+-------------+
|       144034911 |     2015 | Q2          | 269.5       |
|        10500106 |     2015 | Q2          | 303.35      |
|       144034911 |     2015 | Q1          | 231.85      |
|        10500106 |     2015 | Q1          | 250.4       |
|        10500106 |     2014 | Q4          | 276.5       |
|       144034911 |     2014 | Q4          | 224.5       |
+-----------------+----------+-------------+-------------+

我需要显示按 QCD_YEARQCD_QUARTER 排序的底部 2 行,以便最新的季度具有最后的排名(显示为每个组的最后一行) 以前,当只有 2014/Q42015/Q1(即每个 QCD_OUTLET_CODE 有两条记录)时,以下查询可以很好地按我希望的顺序显示记录:

WITH ordered 
     AS (SELECT qcd_outlet_code, 
                qcd_year, 
                qcd_quarter, 
                qcd_credit, 
                Row_number() 
                  over ( 
                    PARTITION BY qcd_outlet_code 
                    ORDER BY qcd_outlet_code, qcd_year, qcd_quarter) 
                AS rn 
         FROM   QTR_CREDIT_DATA) 
SELECT d.qcd_outlet_code    AS "Outlet_Code:string", 
       d.qcd_quarter 
       ||' ' 
       ||d.qcd_year         AS "MCT_quarter:string", 
       Nvl(d.qcd_credit, 0) AS "MCT_Total_Credits_Earned", 
       d.rn                 AS "Display_Order:string" 
FROM   ordered d 
WHERE  rn <= 2; 

每个 QCD_OUTLET_CODE 的两行结果:

+--------------------+--------------------+--------------------------+----------------------+
| Outlet_Code:string | MCT_quarter:string | MCT_Total_Crecits_Earned | Display_Order:string |
+--------------------+--------------------+--------------------------+----------------------+
|           10500106 | Q4 2014            | 387                      |                    1 |
|           10500106 | Q1 2015            | 482.75                   |                    2 |
|          144034911 | Q4 2014            | 269.5                    |                    1 |
|          144034911 | Q1 2015            | 276.5                    |                    2 |
+--------------------+--------------------+--------------------------+----------------------+

请忽略QCD_QUARTER的数字,它们是任意的。

所以Display_Order:string会显示1和2。 但是,对于每个 QCD_OUTLET_CODE 的附加行,我还需要显示每组的底部 2 行(即 2015/Q12015/Q2),我需要它们具有值 1 和 2 Display_Order:string

运行 上面的相同脚本将 return 上面相同的结果(2014/Q42015/Q1)。 如果我在 Partition 子句中使用 DESC,它将 return 我想要的行,但 Display_Order:string 将没有正确的值('2015/Q2' 将给出 1而不是 2)。

我希望从我上面发布的第一个数据集得到的结果如下:

+--------------------+--------------------+--------------------------+----------------------+
| Outlet_Code:string | MCT_quarter:string | MCT_Total_Crecits_Earned | Display_Order:string |
+--------------------+--------------------+--------------------------+----------------------+
|           10500106 | Q1 2015            | 387                      |                    1 |
|           10500106 | Q2 2015            | 482.75                   |                    2 |
|          144034911 | Q1 2015            | 269.5                    |                    1 |
|          144034911 | Q2 2015            | 276.5                    |                    2 |
+--------------------+--------------------+--------------------------+----------------------+

就其价值而言,我试图实现的逻辑就像一个 window 滑过每个组以显示最新的两个季度,并相应地给出行号。

试试这个:

WITH ordered 
     AS (SELECT qcd_outlet_code, 
                qcd_year, 
                qcd_quarter, 
                qcd_credit, 
                Row_number() 
                  over ( 
                    PARTITION BY qcd_outlet_code 
                    ORDER BY qcd_outlet_code, qcd_year DESC, qcd_quarter DESC) 
                AS rn 
         FROM   QTR_CREDIT_DATA) 
SELECT d.qcd_outlet_code    AS "Outlet_Code:string", 
       d.qcd_quarter 
       ||' ' 
       ||d.qcd_year         AS "MCT_quarter:string", 
       Nvl(d.qcd_credit, 0) AS "MCT_Total_Credits_Earned", 
       Row_number() 
                  over ( 
                    PARTITION BY qcd_outlet_code 
                    ORDER BY qcd_outlet_code, qcd_year, qcd_quarter)
                           AS "Display_Order:string" 
FROM   ordered d 
WHERE  rn <= 2;