SQL GROUP BY与聚合

时间:2012-02-15 13:27:42

标签: mysql sql postgresql

如果我有数据表格数字

+------+------+------+------+
| 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行。它按colA, colB分组并选择colD中最大的一个。

不幸的是,这不起作用,因为你还必须按照colC进行分组才能返回它。

为什么呢?还有另一种方法可以做我想做的事吗?

我希望colAcolB中的行与colD中的最大行相同。

3 个答案:

答案 0 :(得分:5)

有几种方法可以解决这个问题。对于执行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

答案 1 :(得分:3)

你可以这样做:

 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;

LEFT JOIN将在同一个表中查找具有相同列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
     )

请注意,如果返回dupe行,您可能需要添加DISTINCT

答案 2 :(得分:0)

您的查询的一个问题是您想要显示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)的所有行。