SQL选择组的第n个成员
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL选择组的第n个成员相关的知识,希望对你有一定的参考价值。
如果我有一个像USER这样的表
class | age
--------------
1 20
3 56
2 11
1 12
2 20
然后我可以轻松地通过每个班级获得最年轻的用户
select class, min(age)
from user
group by class;
同样,通过用max替换min,我可以得到最老的。但是我怎样才能获得每个班级中最年轻(或最老)的第10名?顺便说一下,我正在使用mysql v.5.0。
干杯,
答案
SELECT a.class,
(
SELECT b.age
FROM users b
WHERE b.class = a.class
ORDER BY age
LIMIT 1,1
) as age
FROM users a
GROUP BY a.class
在每堂课中获得第二名最年轻的学生。如果你想要第10个最年轻的,你会做LIMIT 9,1
,如果你想要第10个最老的,你会做ORDER BY age DESC
。
另一答案
在这里N
呈现Nth
记录oldest
SELECT *
FROM users k
WHERE N = (SELECT
COUNT( DISTINCT age)
FROM users u
WHERE k.age >= u.age
AND k.class = u.class
GROUP BY u.class)
并且它给Nth
记录youngest
SELECT *
FROM users k
WHERE N = (SELECT
COUNT(DISTINCT age)
FROM users u
WHERE k.age <= u.age
AND k.class = u.class
GROUP BY u.class)
另一答案
唯一的sql独立方式(即使你没有子查询mysql <5)
select u1.class, u1.age, count(*) from user u1 join user u2
on u1.class = u2.class and u1.age >= u2.age
group by u1.class, u1.age
having count(*) = [number]
获得每个班级最老的[数字]
select u1.class, u1.age, count(*) from user u1 join user u2
on u1.class = u2.class and u1.age <= u2.age
group by u1.class, u1.age
having count(*) = [number]
得到你每班最年轻的[数字]
如果两个人的年龄相同,则可能无法正常工作。如果您只想返回其中一个,则需要一个唯一的密钥,查询会更复杂。
另一答案
在SQL Server中非常简单:
select * from( select *, row_number() over(order by age asc) as eldest from class order by age asc) a where a.eldest = 10
按照这种模式,对于MySQL,我想你想看看这个:http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/
另一答案
任何自己加入表格的答案都会产生一个平方律......
- a JOIN b ON a.class = b.class AND a.age >= b.age
- on average the >= condition will be true for half the class
- 6 people in a class
->6*6/2 = 18
- 10 people in a class
->10*10/2 = 50
-> very rapid growth
随着工作台尺寸的增大,性能将迅速下降。如果你保持小而且不会增长太多,这是一个问题吗?你在那里打电话......
另一种选择涉及更多代码,但线性增长......
- 首先,将所有记录插入到新表中,其中包含IDENTITY字段,按Class排序,然后按Age排序
- 现在,对于每个类,找到MIN(id)
- 现在,对于每个班级,请记录以下内容:= MIN(id)+ 8(对于第9个老人)
最后两步有很多种方法。我个人会用......
SELECT
[USER_WITH_IDS].id,
[USER_WITH_IDS].class,
[USER_WITH_IDS].age
FROM
[USER_WITH_IDS]
WHERE
[USER_WITH_IDS].id = (
SELECT
MIN([min].ID) + 8
FROM
[USER_WITH_IDS] AS [min]
WHERE
[min].class = [USER_WITH_IDS].class
)
这给了...
- 一次创建新ID
- 一次获取每个类的MIN(id)
- 获得所需记录的一遍
- 并且根据优化器的好坏,使用索引(类然后是id)将允许它将最后2个传递组合成1个传递。
无论表格或班级规模有多大,都可以获得2或3次通行证。线性,而不是平方律......
另一答案
SELECT
userid,
class,
age,
( SELECT COUNT(1) FROM user
WHERE class = c.class AND age > u.age
) AS oldercount
FROM user AS u
WHERE oldercount = 9
GROUP BY class
要么
SELECT userid,
class,
age
FROM user AS u
WHERE (SELECT COUNT(1) FROM class WHERE class = c.class AND age > u.age) = 9
GROUP BY class
以上是关于SQL选择组的第n个成员的主要内容,如果未能解决你的问题,请参考以下文章