具有相同最大值的多行

G M*_*ode 4 mysql greatest-n-per-group

当我运行以下查询时,

SELECT engines, manufacturer, model, MAX(seats)
FROM   planes
GROUP BY engines;
Run Code Online (Sandbox Code Playgroud)

我得到了正确的引擎和座椅结果,但不是正确的制造商、型号组合。此外,我需要的座位数有多个具有相同最大值的行,但引擎/座位只得到一个结果。我已经查看了其他 Stack Exchange 帖子和其他地方,但似乎找不到解决查询的好方法。有什么建议吗?

And*_*y M 7

您的问题似乎是“每组最大的 N”问题。您可以做的是获得每个引擎结果的最大座位数:

SELECT
  engines,
  MAX(seats) AS max_seats
FROM
  planes
GROUP BY
  engines
Run Code Online (Sandbox Code Playgroud)

并将它们用作派生表,将它们连接回源以获得与最大值匹配的行:

SELECT
  p.engines,
  p.manufacturer,
  p.model,
  es.max_seats
FROM
  planes AS p
  INNER JOIN
  (
    SELECT
      engines,
      MAX(seats) AS max_seats
    FROM
      planes
    GROUP BY
      engines
  ) AS es
  ON p.engines = es.engines
  AND p.seats = es.max_seats
;
Run Code Online (Sandbox Code Playgroud)


Len*_*art 5

问题是选择中的列比分组依据中的列多。MySQL 中的默认设置允许这样做,但可能会导致不确定的结果。例子:

engines, manufacturer, model, seats
A        A            A       10
A        B            C       20
Run Code Online (Sandbox Code Playgroud)

您的查询:

SELECT engines, manufacturer, model, MAX(seats)
FROM   planes
GROUP BY engines;
Run Code Online (Sandbox Code Playgroud)

那么意味着,“获取发动机‘A’的最大座位数,并随机选择‘A’的制造商/型号。这可能意味着:

+---------+--------------+-------+------------+
| engines | manufacturer | model | MAX(seats) |
+---------+--------------+-------+------------+
| A       | A            | B     |         20 |
+---------+--------------+-------+------------+
Run Code Online (Sandbox Code Playgroud)

但也可能是:

+---------+--------------+-------+------------+
| engines | manufacturer | model | MAX(seats) |
+---------+--------------+-------+------------+
| A       | B            | C     |         20 |
+---------+--------------+-------+------------+
Run Code Online (Sandbox Code Playgroud)

您可以通过要求完整的组来防止这种情况:

MariaDB [test]> set @@sql_mode = 'ONLY_FULL_GROUP_BY'
-> ;
Query OK, 0 rows affected (0,01 sec)

MariaDB [test]> SELECT engines, manufacturer, model,  MAX(seats)     FROM   planes     GROUP BY engines;
ERROR 1055 (42000): 'test.planes.manufacturer' isn't in GROUP BY
Run Code Online (Sandbox Code Playgroud)

如果您想要拥有最多座位的发动机的制造商/型号,您可以首先获取发动机的最大座位,然后加入原始表,如 @Andriy M 答案:

SELECT A.engines, B.manufacturer, B.model, A.seats 
from (
    SELECT engines, MAX(seats) as seats    
    FROM   planes     
    GROUP BY engines
) as A 
join planes B 
    on A.engines = B.engines 
   and A.seats = B.seats;

+---------+--------------+-------+-------+
| engines | manufacturer | model | seats |
+---------+--------------+-------+-------+
| A       | B            | C     |    20 |
+---------+--------------+-------+-------+
Run Code Online (Sandbox Code Playgroud)

其他 DBMS(例如 PostgreSQL、Oracle、DB2 和 SQL-Server)提供了窗口函数,使这种查询变得更容易:

select engines, manufacturer, model, seats
from (
    select engines, manufacturer, model, seats
         , row_number() over (partition by engine
                              order by seats desc) as rn
    from planes
) where rn = 1;
Run Code Online (Sandbox Code Playgroud)