2017-05-22 64 views
0

我有一個表在AS400如下排名和分區查詢在SQL

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 

我需要的是每種類型的前2有一個狀態,即Y.結果應該像A 1 , A 3, B 2 , C3, C4, D3, D5, E3, E7.

我曾經用過的查詢是這個

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; 

這裏的問題是它沒有事先篩選出的狀態。它拿起前兩個,然後用Y過濾掉。所以結果看起來像A1而不是A1和A3,因爲它先選擇了A1和A2,然後過濾了A2。 我在哪裏插入Status = y以獲得更準確的結果。 我是SQL中的新手,所以如果還有更好的方式來編寫上述查詢,那我也沒問題。

+0

我無法格式化的表格更加清晰以上:) – user8049037

+0

把你的WHERE子句中的'狀態= Y'位到子查詢。考慮到你的數據,將'Type IN(A,B,C,D,E)'部分粘貼到你的子查詢中也是有道理的。 – JNevill

+0

@JNevill - 常識,但工作絕對完美。乾杯! – user8049037

回答

0

This outta do it。使用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