简体   繁体   English

SQL中的排名和分区查询

[英]Rank and partition query in SQL

I have a table in AS400 as below 我在AS400中有一张桌子,如下所示

Type    Values  Status
A   1   Y
A   2   N
A   3   Y
A   4   Y
A   5   N
B   2   Y
B   7   N
C   3   Y
C   5   N
C   4   Y
C   6   Y
C   7   Y
C   1   Y
D   3   Y
D   5   Y
E   7   N
E   4   N
E   3   Y
E   6   N
E   7   Y
E   8   N

What I need is Top 2 of each type that have a status YIe the result should be something like A 1 , A 3, B 2 , C3, C4, D3, D5, E3, E7. 我需要的是状态为Yee的每种类型的前2个,结果应该是A 1 , A 3, B 2 , C3, C4, D3, D5, E3, E7.

The query I have used is this 我使用的查询是这样

SELECT type,
    REFERENCES
FROM (
    SELECT type,
        REFERENCES,
        STATUS,
        rank() OVER (PARTITION BY Type ORDER BY REFERENCES DESC) AS Rank
    FROM Tables
    ) a
WHERE rank <= 2
    AND Type IN (A,B,C,D,E)
    AND STATUS = Y;

The issue here is it doesn't filter out the status beforehand. 这里的问题是它不会事先过滤掉状态。 It picks up the top 2, then filters out with Y. So the result looks something like A1 instead of A1 and A3, because it has first picked A1 and A2 , and then filtered out A2 . 它选择前2个,然后用Y过滤。因此结果看起来像A1而不是A1和A3,因为它首先选择了A1和A2,然后过滤了A2。 Where do I insert the Status=y to get a more accurate result. 我在哪里插入Status = y以获得更准确的结果。 I am a novice in SQL so if theres a better way to write the above query as well, I am fine with that. 我是SQL的新手,所以如果还有更好的方法编写上述查询,我​​也很好。

This outta do it. 这不行。 Use the with clause to feed the filtered result into a new query which then you can rank. 使用with子句将过滤后的结果输入到新查询中,然后可以对其进行排名。

with testtable (type, value, status) as (
select 'A', 1, 'Y' from dual union all
select 'A', 2, 'N' from dual union all
select 'A', 3, 'Y' from dual union all
select 'A', 4, 'Y' from dual union all
select 'A', 5, 'N' from dual union all
select 'B', 2, 'Y' from dual union all
select 'B', 7, 'N' from dual union all
select 'C', 3, 'Y' from dual union all
select 'C', 5, 'N' from dual union all
select 'C', 4, 'Y' from dual union all
select 'C', 6, 'Y' from dual union all
select 'C', 7, 'Y' from dual union all
select 'C', 1, 'Y' from dual union all
select 'D', 3, 'Y' from dual union all
select 'D', 5, 'Y' from dual union all
select 'E', 7, 'N' from dual union all
select 'E', 4, 'N' from dual union all
select 'E', 3, 'Y' from dual union all
select 'E', 6, 'N' from dual union all
select 'E', 7, 'Y' from dual union all
select 'E', 8, 'N' from dual
)
, ys as (
select
*
from testtable
where STATUS = 'Y'
)
, yrank as (
select
type, 
value,
status,
rank() over(partition by type order by value) Y_RANK
from ys
)
select
*
from yrank
where Y_RANK <= 2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM