SQL查询以选择具有最小值的不同行
Posted
技术标签:
【中文标题】SQL查询以选择具有最小值的不同行【英文标题】:SQL query to select distinct row with minimum value 【发布时间】:2013-02-23 20:24:48 【问题描述】:我想要一条 SQL 语句来获取具有最小值的行。
考虑这张表:
id game point
1 x 5
1 z 4
2 y 6
3 x 2
3 y 5
3 z 8
如何选择在point
列中具有最小值的ID,按游戏分组?像下面这样:
id game point
1 z 4
2 y 5
3 x 2
【问题讨论】:
您需要加入同一张表才能获得所需的结果。在答案中检查下面的查询。 为什么你的结果中游戏“y”点值是 6 而不是 5? 由于 OP 没有回应,我只能假设他的意思是问“按 id 分组”,并显示哪个游戏得分最低... 【参考方案1】:试试:
select id, game, min(point) from t
group by id
【讨论】:
我收到此错误“列 'student.point' 在 HAVING 子句中无效,因为它不包含在聚合函数或 GROUP BY 子句中。” 这不会得到想要的结果。因为您需要将查询与 id、game、point to remove error 分组,这将返回所有记录。 对不起,我不明白。这里有什么问题:sqlfiddle.com/#!2/8b9c7/8/0 代码是:select id, game, min(point) from tablename group by id,game @Wawrzyniec - 问题是您的结果不正确。 ID 1, game z, min(point) 4 应该是正确的。【参考方案2】:这会起作用
select * from table
where (id,point) IN (select id,min(point) from table group by id);
【讨论】:
你使用的是哪个 rdbms? 哦!我不了解 mysql ...该查询是子查询中的多列检查,它将在 Oracle 中工作。 好的。感谢您的支持【参考方案3】:用途:
SELECT tbl.*
FROM TableName tbl
INNER JOIN
(
SELECT Id, MIN(Point) MinPoint
FROM TableName
GROUP BY Id
) tbl1
ON tbl1.id = tbl.id
WHERE tbl1.MinPoint = tbl.Point
【讨论】:
在Microsoft access中写SQL时可以做单个内连接吗?? 不必要的完成 SELECT id , game , MIN(point) FROM tablename GROUP BY id,game @SouravSarkar,这将不起作用该示例将返回原始查询的每一行,因为它正在寻找每个 id 和游戏的最低点。 (例如,id = 1 和 game = x 的最低分数是 5;id = 1 和 game = z 的最低分数是 4) 我同意。这是不必要的。使用 Window 函数是一种更简洁的方法,并且与架构无关,也可以减少对连接的需求。 如前所述,当有两行id相同,最小值如[id, game, point] [1, x, 4][1, y, 4] 【参考方案4】:Ken Clark's answer 在我的情况下不起作用。它也可能不适用于您的。如果没有,试试这个:
SELECT *
from table T
INNER JOIN
(
select id, MIN(point) MinPoint
from table T
group by AccountId
) NewT on T.id = NewT.id and T.point = NewT.MinPoint
ORDER BY game desc
【讨论】:
【参考方案5】:SELECT * from room
INNER JOIN
(
select DISTINCT hotelNo, MIN(price) MinPrice
from room
Group by hotelNo
) NewT
on room.hotelNo = NewT.hotelNo and room.price = NewT.MinPrice;
【讨论】:
对这段代码如何回答问题的简短解释将大大改善这个答案【参考方案6】:由于仅使用sql
标记,以下使用ANSI SQL 和window function:
select id, game, point
from (
select id, game, point,
row_number() over (partition by game order by point) as rn
from games
) t
where rn = 1;
【讨论】:
【参考方案7】:这是做同样事情的另一种方式,它可以让你做一些有趣的事情,比如选择前 5 名获胜的游戏等。
SELECT *
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Point) as RowNum, *
FROM Table
) X
WHERE RowNum = 1
您现在可以正确获取被识别为得分最低的实际行,并且您可以修改排序函数以使用多个标准,例如“显示得分最低的最早游戏”等。
【讨论】:
【参考方案8】:此替代方法使用 SQL Server 的 OUTER APPLY
子句。这样,它
-
创建不同的游戏列表,并
获取并输出该游戏得分最低的记录。
OUTER APPLY
子句可以想象成LEFT JOIN
,但优点是您可以将主查询的值用作子查询中的参数(此处为游戏)。 p>
SELECT colMinPointID
FROM (
SELECT game
FROM table
GROUP BY game
) As rstOuter
OUTER APPLY (
SELECT TOP 1 id As colMinPointID
FROM table As rstInner
WHERE rstInner.game = rstOuter.game
ORDER BY points
) AS rstMinPoints
【讨论】:
【参考方案9】:SELECT DISTINCT
FIRST_VALUE(ID) OVER (Partition by Game ORDER BY Point) AS ID,
Game,
FIRST_VALUE(Point) OVER (Partition by Game ORDER BY Point) AS Point
FROM #T
【讨论】:
什么是#T
?你还没有定义,所以你的答案不完整。【参考方案10】:
这是可移植的——至少在 ORACLE 和 PostgreSQL 之间:
select t.* from table t
where not exists(select 1 from table ti where ti.attr > t.attr);
【讨论】:
这应该如何回答这个问题? 查询选择同一张表中没有其他记录且属性值较大的记录。如果多行具有相同的最小属性值,则全部返回。``` select t.* from table t where not exists(select 1 from table ti where ti.attr > t.attr); ``` 即使您的答案是正确的,通过使用随机的表名和列名,您也很难看到您的答案和问题之间的关系。以上是关于SQL查询以选择具有最小值的不同行的主要内容,如果未能解决你的问题,请参考以下文章
MySQL Select ID 出现在具有多个特定值的列的不同行上