Оракул выбора ранга SQL

У меня такая проблема, что моя таблица выглядит так:

REC_ID | Year | status | -------|-----------|----------| 123 | 2016 | OA | 123 | 2017 | CC |

Мой запрос должен проверить, соответствует ли rec_id ? если

  1. Существует запись за 2016 год, в которой статус OA, затем выберите эту строку.
  2. Существует запись за 2016 год, где статус – любой другой статус (не OA), а записи за 2017 год не существует, а затем выберите эту строку (строка 2016 года).
  3. Существует запись за 2016 год с любым другим статусом (не OA), и запись существует за 2017 год, затем выберите запись за 2017 год.

поэтому в приведенном выше примере должна быть выбрана запись 2016 года.

REC_ID | Year | status | -------|-----------|----------| 456 | 2016 | OP |

в этом примере, поскольку есть только одна запись, должна быть выбрана запись 2016 года.

REC_ID | Year | status | -------|-----------|----------| 789 | 2016 | OM | 789 | 2017 | CC |

В этом последнем примере, поскольку есть две записи, и 2016 НЕ является OA, запись 2017 должна быть выбрана.

Я попытался ранжировать их, но это не сработало, и попытался сделать что-то вроде ниже, но обе записи были подобраны.

 SELECT CASE
WHEN (STATUS = 'OA'
    AND YEAR              = TO_CHAR(SYSDATE, 'YYYY')
    AND ?= REC_ID)
    OR ((SELECT COUNT(*)
      FROM TABLE
      WHERE ?= REC_ID
      AND YEAR = TO_CHAR(add_months(sysdate, 12), 'YYYY' ))= 0)
    THEN TABLE.STATUS
    ELSE
      (SELECT STATUS
      FROM TABLE
      WHERE ?= REC_ID
      AND YEAR       = TO_CHAR(add_months(sysdate, 12), 'YYYY' )
      )
  END from TABLE WHERE ?= REC_ID ;

person Mohamed    schedule 30.11.2016    source источник
comment
Правила кажутся недостаточными. Что делать, если есть только строки за 2016 год, нет строки за 2017 год, ни одна строка не имеет статуса OA, но имеется более одной строки? Например, 2016 CC и 2016 AD. Какой из этих рядов следует выбрать? Кроме того, если нет строки с 2016 и OA, но более одной строки с 2017 - КАКУЮ строку с 2017 следует выбрать?   -  person mathguy    schedule 01.12.2016


Ответы (2)


Переформулировка рейтинга:

  1. 2016 И статус = 'OA'
  2. 2017
  3. 2016

Запрос с ROW_NUMBER для выбора наилучшего совпадения по rec_id:

select rec_id, year, status
from
(
  select 
    rec_id, year, status,
    row_number() OVER (partition by rec_id
               order by case 
                 when year = 2016 and status = 'OA' then 1 
                 when year = 2017 then 2
                 else 3
               end) as rn
  from mytable
  where year in (2016, 2017)
)
where rn = 1;
person Thorsten Kettner    schedule 30.11.2016

Это запрос определения приоритетов, который предлагает использовать row_number(). Я думаю, вы хотите:

select t.*
from (select t.*,
             row_number() over (partition by rec_id
                                order by (case when year = 2016 and status = 'OA' then 1 else 2 end),
                                         year desc
                               ) as seqnum
      from table t
      where year in (2016, 2017)
     ) t
where seqnum = 1;
person Gordon Linoff    schedule 30.11.2016