SQL 查询每个组 ID 仅返回 1 条记录
Posted
技术标签:
【中文标题】SQL 查询每个组 ID 仅返回 1 条记录【英文标题】:SQL query to return only 1 record per group ID 【发布时间】:2009-12-23 17:31:15 【问题描述】:我正在寻找一种方法来处理以下情况。我有一个数据库表,我只需要为表中包含的每个“组 id”返回一条记录,此外,在每个组中选择的记录应该是家庭中最年长的人。
ID Group ID Name Age
1 134 John Bowers 37
2 134 Kerri Bowers 33
3 135 John Bowers 44
4 135 Shannon Bowers 42
因此,在上面提供的示例数据中,我需要返回 ID 1 和 3,因为它们是每个组 ID 中最年长的人。
这是针对 SQL Server 2005 数据库查询的。
【问题讨论】:
如果你想要名字,如果你有>1个年龄最大的人,你仍然有机会选择>1行。在这种情况下,您还应该建立选择名称的标准。 好点克里斯。是想稍微简化一下这个问题,但这留下了这样的漏洞 :-) 我实际上还有另一个性别领域,所以我希望选择一个家庭中最年长的男性。如果有男性,那么最年长的女性。如果同一家庭中有两个年龄相同的男性,那么我只需要选择其中一条记录。这可以基于一些简单的事情,比如在决胜局中拥有最低 ID 号的人。 Joe Celko 的优秀著作“Smarties 的 SQL”的第 21.4 节“极值函数”对这类问题进行了很好的讨论。如果您遇到比简单的 SELECT 和 INSERT 更棘手的问题,我强烈推荐这本书。 【参考方案1】:SELECT t.*
FROM (
SELECT DISTINCT groupid
FROM mytable
) mo
CROSS APPLY
(
SELECT TOP 1 *
FROM mytable mi
WHERE mi.groupid = mo.groupid
ORDER BY
age DESC
) t
或者这个:
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY groupid ORDER BY age DESC) rn
FROM mytable
) x
WHERE x.rn = 1
即使在平局的情况下,每组最多返回一条记录。
有关两种方法的性能比较,请参阅我的博客中的这篇文章:
SQL Server: Selecting records holding group-wise maximum【讨论】:
+1:是的,忘了我关于关系的免责声明。忙于灭火。 谢谢夸斯诺伊。我能够将性别列添加到您的 ORDER By 子句中的年龄列中,并获得我正在寻找的结果! (在我最初的问题之后,仅在评论中讨论了性别专栏)您的解决方案是完美的,适应性强! 跟进问题。这些将针对 1.75 亿条记录运行。一个或另一个查询更有效吗?@Richard West
: 你有多少个不同的组?你有一个单独的表格来包含这些组吗?
由于某种原因,SQL Server 给了我Msg 156, Level 15, State 1, Line 7 Incorrect syntax near the keyword 'WHERE'
。【参考方案2】:
用途:
SELECT DISTINCT
t.groupid,
t.name
FROM TABLE t
JOIN (SELECT t.groupid,
MAX(t.age) 'max_age'
FROM TABLE t
GROUP BY t.groupid) x ON x.groupid = t.groupid
AND x.max_age = t.age
如果一个组有 2 个以上的同龄人怎么办?最好存储生日而不是年龄 - 您始终可以计算年龄以进行演示。
【讨论】:
【参考方案3】:试试这个(假设 Group 是 Household 的同义词)
Select * From Table t
Where Age = (Select Max(Age)
From Table
Where GroupId = t.GroupId)
如果某个家庭中有两个或更多“最年长”的人(他们的年龄相同,并且没有其他人年长),那么这将返回所有这些人,而不是随机返回一个。
如果这是一个问题,那么您需要添加另一个子查询来为该集合中的一个人返回任意键值。
Select * From Table t
Where Id =
(Select Max(Id) Fom Table
Where GroupId = t.GroupId
And Age =
(Select(Max(Age) From Table
Where GroupId = t.GroupId))
【讨论】:
【参考方案4】:SELECT GroupID, Name, Age
FROM table
INNER JOIN
(
SELECT GroupID, MAX(Age) AS OLDEST
FROM table
) AS OLDESTPEOPLE
ON
table.GroupID = OLDESTPEOPLE.GroupID
AND
table.Age = OLDESTPEOPLE.OLDEST
【讨论】:
以上是关于SQL 查询每个组 ID 仅返回 1 条记录的主要内容,如果未能解决你的问题,请参考以下文章