2015-11-05 83 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()功能。