SQL排名选择oracle

时间:2016-11-30 21:52:48

标签: sql oracle rank

我遇到的问题是我的表格如下所示;

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年的记录
  4. 所以在上面的例子中,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 ;
    

2 个答案:

答案 0 :(得分:0)

这是一个优先级查询,建议使用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 :(得分:0)

重新排列排名:

  1. 2016 AND status =' OA'
  2. 2017
  3. 2016
  4. 使用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;