SQL查询以选择具有最小值的不同行

时间:2013-03-08 10:12:36

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

我想要一个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      6
3    x      2   

10 个答案:

答案 0 :(得分:43)

使用:

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

答案 1 :(得分:13)

这将有效

select * from table 
where (id,point) IN (select id,min(point) from table group by id);

答案 2 :(得分:12)

这是做同样事情的另一种方式,它可以让你做一些有趣的事情,比如选择前5名获胜游戏等。

 SELECT *
 FROM
 (
     SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Point) as RowNum, *
     FROM Table
 ) X 
 WHERE RowNum = 1

您现在可以正确获取被识别为分数最低的实际行,并且您可以修改排序功能以使用多个条件,例如“向我显示分数最小的最早的游戏”等。

答案 3 :(得分:11)

由于此标记仅为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;

答案 4 :(得分:0)

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 :(得分:0)

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 :(得分:0)

此替代方法使用SQL Server的OUTER APPLY子句。这样,

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

OUTER APPLY子句可以想象成LEFT JOIN,但是它的优点是您可以使用主查询的值作为子查询中的参数(此处为game )。

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

这是可移植的-至少在ORACLE和PostgreSQL之间:

select t.* from table t 
where not exists(select 1 from table ti where ti.attr > t.attr);

答案 9 :(得分:-3)

尝试:

select id, game, min(point) from t
group by id