SQL 排名选择神谕
SQL Rank selection oracle
我有一个问题,我的 table 如下所示;
REC_ID | Year | status |
-------|-----------|----------|
123 | 2016 | OA |
123 | 2017 | CC |
我的查询应该检查是否 rec_id?如果
- 2016 年有一条状态为 OA 的记录,然后选择该行。
- 有一条 2016 年的记录,其状态为任何其他状态(非 OA),而 2017 年不存在任何记录,然后选择该行(2016 行)。
- 有 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;
改写排名:
- 2016 年和状态 = 'OA'
- 2017
- 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;
我有一个问题,我的 table 如下所示;
REC_ID | Year | status |
-------|-----------|----------|
123 | 2016 | OA |
123 | 2017 | CC |
我的查询应该检查是否 rec_id?如果
- 2016 年有一条状态为 OA 的记录,然后选择该行。
- 有一条 2016 年的记录,其状态为任何其他状态(非 OA),而 2017 年不存在任何记录,然后选择该行(2016 行)。
- 有 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;
改写排名:
- 2016 年和状态 = 'OA'
- 2017
- 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;