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 出现在具有多个特定值的列的不同行上

在 SQL 中选择具有一个最大值但另一个最小值的项目 [关闭]

如何使用 LINQ 选择具有最小或最大属性值的对象

sql查询时间最小值的列

SQL 查询表以查找特定列的最小值 >= X 的行

如何在 MySQL 中选择字段具有最小值的数据?