SQL 排名选择神谕

SQL Rank selection oracle

我有一个问题,我的 table 如下所示;

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 ;

这是一个优先查询,建议使用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;

改写排名:

  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;