2015-11-05 94 views
0
create table tab1(sno int, name varchar(30), age int); 

insert into tab1 values(1, 'abc1', 22); 
insert into tab1 values(2, 'abc2', 23); 
insert into tab1 values(3, 'xyz', 28); 
insert into tab1 values(4, 'abc3', 26); 
insert into tab1 values(5, 'abc4', 25); 

select sno, name, age, rank() over (order by sno) as ranking from tab1 where 
ranking = trunc((select count(*)/2 from tab1)) + 1; //This query is giving error 

錯誤是ORA-00904使用:「排行榜」:無效的標識符別名排名不能在where子句

+0

@TimSchmelter Edited。 – Alvin3001

回答

3

您正試圖根據在所有過濾完成後計算出的值來過濾選擇的結果。你需要改變它是這樣的:

select * from (
    select sno, name, age, rank() over (order by sno) as ranking from tab1 
) where ranking = trunc((select count(*)/2 from tab1)) + 1; 
2

您的問題是謝謝你在select定義一個別名,然後你想要篩選它。您需要使用CTE或子查詢:

with cte as (
     select sno, name, age, rank() over (order by sno) as ranking 
     from tab1 
    ) 
select cte.* 
from cte 
where cte.ranking = trunc((select count(*)/2 from tab1)) + 1; 

您似乎想要計算中值。我絕對不會爲此推薦rank(),因爲它處理關係的方式。一個更好的選擇是row_number(),所以這很接近獲得中位數。而且,您不需要子查詢:

with cte as (
     select sno, name, age, row_number() over (order by sno) as ranking, 
      count(*) over() as cnt 
     from tab1 
    ) 
select cte.* 
from cte 
where 2*cte.ranking in (cnt, cnt + 1) 

這對於偶數和奇數行都可以正常工作。

您可能也有興趣MEDIAN()PERCENTILE_DISC()PERCENTILE_CONT()功能。