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

我需要一个 SQL 语句来获取具有最小值的行。

看看这张表:

id  game   point
1    x      5
1    z      4
2    y      6
3    x      2
3    y      5
3    z      8

我如何选择的 id 有最小值的 point列,按游戏分组?如下所示:

id  game   point
1    z      4
2    y      5
3    x      2
261909 次浏览

试试:

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

会成功的

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

用途:

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
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;

由于这只用 sql标记,因此下面使用的是 ANSI SQL 和 窗口功能:

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;

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

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

现在,您可以正确地获得被标识为得分最低的实际行,并且您可以修改排序函数以使用多个标准,例如“给我看看得分最低的最早的游戏”,等等。

这种替代方法使用 SQLServer 的 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
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

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

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

大多数的答案使用一个内部查询。我想知道为什么下面的不建议。

select
*
from
table
order by
point
fetch next 1 row only   // ... or the appropriate syntax for the particular DB

使用 JPAQueryFactory(JavaQueryDSL 类)编写此查询非常简单。

return new JPAQueryFactory(manager).
selectFrom(QTable.table).
setLockMode(LockModeType.OPTIMISTIC).
orderBy(QTable.table.point.asc()).
fetchFirst();