2015-07-13 5 views
0

У меня есть таблица выглядит следующим образом:Как выбрать нижний N строк из каждой группы - Oracle 11g

 
+-----------------+----------+-------------+-------------+ 
| 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  | 
+-----------------+----------+-------------+-------------+ 

мне нужно, чтобы отобразить нижние 2 ряда заказанные QCD_YEAR и QCD_QUARTER таким образом, что последняя четверть имеет последний ранг (отображается в последней строке для каждой группы) Раньше, когда было только 2014/Q4 и 2015/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/Q1 и 2015/Q2) и мне нужно им иметь значения 1 и 2 для Display_Order:string

Выполнение того же сценария выше вернет тот же результат выше (2014/Q4 и 2015/Q1). Если я использую DESC в пункте Partition, он вернет строки, которые я хочу, но 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 | 
+--------------------+--------------------+--------------------------+----------------------+ 

своей ценности, логика я пытаюсь осуществить это как окно, которое скользит по каждой группе, чтобы отобразить последние два квартала, и соответственно присвоить номера строк.

+0

Используйте '' DESC' в row_number() над (PARTITION BY qcd_outlet_code ORDER BY qcd_outlet_code, qcd_year DESC, qcd_quarter DESC) ';). –

+0

@ shA.t Это супер быстрый ответ. Если вы имеете в виду то, что я упомянул о моем вопросе (порядок разделов по описанию), он не вернул правильный номер строки, который я хочу. Он дает 1 к последней четверти, в то время как я хочу, чтобы он дал от 2 до последних, от 1 до первого – Hawk

+0

@Hawk. Положите 'DESC' в' ORDER BY' предложение, а не раздел и дайте нам знать результат. Помните, что ** ЗАКАЗ ** гарантируется ТОЛЬКО, когда указывается ORDER BY. Чтобы получить обратный порядок, вы должны использовать DESC. –

ответ

1

Попробуйте это:

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; 
+0

Добавление 'over partition' к основному запросу, а также добавление' desc' в раздел раздела CTE сделали трюк. большое спасибо – Hawk

Смежные вопросы