2014-06-11 72 views
1

下面是一个包含20个项目的测试表。选择具有特定行号值的行

create table test (id int not null primary key); 
insert into test values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19); 

我可以这样添加行号列(提琴:http://sqlfiddle.com/#!2/dade4/3):

select id, @r:[email protected]+1 r 
from test a 
join (select @r:=0) b; 

然后我试图让第一10个项目有HAVING条款(小提琴:http://sqlfiddle.com/#!2/dade4/4):

select id, @r:[email protected]+1 r 
from test a 
join (select @r:=0) b 
having r <= 10; 

这里有意想不到的结果:

ID| R 
------ 
0 | 2 
1 | 4 
2 | 6 
3 | 8 
4 | 10 

这是为什么,以及如何检索r在1和10之间的行?

(我没有使用限制,因为在不同的查询,我需要选择每个类别的前n项)

回答

1

我与其他的答案一致,having是没有办法的办法,但如果你需要使用它,那么:

select id, @r:[email protected]+1 r 
    from test a 
    join (select @r:=0) b 
having @r+1 <= 10; 

这里demo in SQLFiddle

你之所以得到错误结果的原因是因为MySql计算两次别名r(在select和in中),所以@r:[email protected]+1被执行两次。

1

HAVING,除非你在聚合(SUM()是没有意义的,COUNT()GROUP BY)查询。

您需要将您的rownumbering封装在适当的子查询中(http://sqlfiddle.com/#!2/dade4/6/0)。

select id, r 
    from (select id, @r:[email protected]+1 r 
     from test a 
     join (select @r:=0) b 
    ) as q 
where r <= 10; 
1

我遇到了类似的问题,当我回答这个问题:

Mysql: Gap detection query not detecting gaps

的MySQL显然执行HAVING测试,因为它是产生结果时,没有聚集正在做,这将导致一些短路。

解决方案是使用子查询。

select id, r 
    from (select id, @r:[email protected]+1 r 
     from test a 
     join (select @r:=0) b 
    ) as q 
where r <= 10;