【问题标题】:SQL query to select distinct row with minimum valueSQL查询以选择具有最小值的不同行
【发布时间】: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 分组”,并显示哪个游戏得分最低...

标签: sql database greatest-n-per-group


【解决方案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 子句。这样,它

        1. 创建不同的游戏列表,并
        2. 获取并输出该游戏得分最低的记录。

        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); ```
          • 即使您的答案是正确的,通过使用随机的表名和列名,您也很难看到您的答案和问题之间的关系。
          猜你喜欢
          • 1970-01-01
          • 2016-01-21
          • 2023-03-30
          • 2019-08-05
          • 1970-01-01
          • 2021-03-18
          • 2011-06-20
          • 2013-10-26
          • 1970-01-01
          相关资源
          最近更新 更多