Mysql 具有聚合的SQL GROUP BY

Mysql 具有聚合的SQL GROUP BY,mysql,sql,postgresql,Mysql,Sql,Postgresql,如果我有一个带有数据的表编号: +------+------+------+------+ | colA | colB | colC | colD | +------+------+------+------+ | 1 | 2 | 3 | 4 | | 1 | 2 | 9 | 5 | +------+------+------+------+ 并且做: select colA, colB, colC, MAX(colD) FROM Numbers

如果我有一个带有数据的表编号:

+------+------+------+------+
| colA | colB | colC | colD |
+------+------+------+------+
|    1 |    2 |    3 |    4 |
|    1 |    2 |    9 |    5 |
+------+------+------+------+
并且做:

select colA, colB, colC, MAX(colD) FROM Numbers GROUP BY colA, colB;
我认为它应该返回第2排。它按可乐、可乐进行分组,并在冷饮料中选择最大的可乐

不幸的是,这不起作用,因为您还必须按colC分组才能返回它

为什么??有没有其他方法来做我想做的事情


我希望在
colA
colB
中使用相同的行,但在
colD
中使用最大的行

查询的问题之一是,您希望显示codC的值,但它不在分组中。若要在不使用agregate函数的情况下显示该值,该值必须位于分组中。因此,要修复查询,可以执行以下操作:

select n1.* from Number n1
inner join (select colA, colB, max(colD) as colD from Number GROUP BY colA, colB) n2 on n1.colA = n2.colA and n1.colB = n2.colB and n1.colD = n2.colD
它将为每个colA和colB选择带有max(colD)的所有行。

您可以执行以下操作:

 SELECT N1.colA, N1.colB, N1.colC, N1.colD
   FROM Numbers N1
   LEFT JOIN Numbers N2 ON N2.colA = N1.colA
                       AND N2.colB = N1.colB
                       AND N2.colD > N1.colD
  WHERE N2.colA IS NULL;
左联接将查找同一表中具有相同列a和B以及更大列D的行。如果未找到行,则在列D中具有最大值

这在技术上与:

SELECT *
  FROM Numbers N
 WHERE NOT EXISTS
     ( SELECT NULL /* or whatever you want, doesn't matter */
         FROM Numbers
        WHERE colA = N.colA
          AND colB = N.colB
          AND colD > N.colD
     )

请注意,如果返回重复行,您可能需要添加一个
DISTINCT

有几种方法可以处理此问题。也许最简单的方法是对子查询进行
JOIN
,该子查询执行
colA,colB
组,并从中找到完整的对应行

SELECT 
  tbl.colA,
  tbl.colB,
  tbl.colC,
  tbl.colD
FROM tbl JOIN (
  SELECT
    colA,
    colB,
    MAX(colD) AS maxD
  FROM tbl
  GROUP BY colA, colB
) g ON tbl.colA = g.colA AND tbl.colB = g.colB AND tbl.colD = g.maxD

谢谢,谢谢Benoit重构了这个问题:)如果两个列名都是相同的,那么真的需要将所有列名都命名为“on”:s吗?@Hamidam是的,只要其中一个不是主键,您就需要在
on
子句中列出所有列名。例如,如果
colA
是唯一的键值,你可以在tbl.colA=g.colA上执行
,但由于你的键值不是唯一的,你需要组合尽可能多的列来生成唯一的值
colA,colB,MAX(colD)
我在想我们的大学老师(很久以前)说过的一句话,如果名字(列名)在这两个方面都是一样的,而不是你不需要的。但是不确定这是否与连接或其他东西有关,也许是联合…@Hamidam听起来像是与
联合
有关,而不是与
连接
有关。无论如何,在SQL查询中总是最好尽可能明确。对于某些事情,不鼓励使用快捷方式像
SELECT*
。我认为不是
NATURAL JOIN
,而是
JOIN…使用(col1,col2,col3)
。这将有两个好处:更精确一点(“嘿,db,JOIN-an-the-columns”vs.“嘿,db,JOIN-on-on-some-expression,我希望我做得对”),同时显示正在发生的全部信息。