使用MAX()和GROUP BY时如何选择整个记录

rsw*_*lff 3 mysql sql greatest-n-per-group

使用MYSQL我想重构以下SELECT语句以返回包含最新内容invoice_date整个记录:

> SELECT id, invoice, invoice_date
  FROM invoice_items
  WHERE lot = 1047

id    invoice_id   invoice_date
-----------------------------------
3235    1047         2009-12-15 11:40:00
3295    1047         2009-12-15 16:00:00
3311    1047         2009-12-15 09:30:00
3340    1047         2009-12-15 13:50:00
Run Code Online (Sandbox Code Playgroud)

使用MAX()聚合函数和GROUP BY子句让我成为那里的一部分:

> SELECT id, invoice_id, max(invoice_date)
  FROM invoice_items
  WHERE invoice_id = 1047
  GROUP BY invoice_id


id    invoice_id   invoice_date
-----------------------------------
3235    1047         2009-12-15 16:00:00
Run Code Online (Sandbox Code Playgroud)

请注意,查询似乎MAX(invoice_date)正确,但id返回的(3235)不是id包含MAX(invoice_date)(3295)的记录,它是id初始查询中第一条记录的记录.

如何重构此查询以向我提供包含整个记录MAX(invoice_date)

解决方案必须使用GROUP BY子句,因为我需要invoice_date为每个发票获取最新信息.

Bil*_*win 7

这是经常重复的"每组最大n"问题.

以下是我在MySQL中解决它的方法:

SELECT i1.*
FROM invoice_items i1
LEFT OUTER JOIN invoice_items i2
  ON (i1.invoice_id = i2.invoice_id AND i1.invoice_date < i2.invoice_date)
WHERE i2.invoice_id IS NULL;
Run Code Online (Sandbox Code Playgroud)

说明:对于每一行i1,尝试查找i2具有相同invoice_id和更大日期的行.如果没有找到(即i2由于外连接而全部为空),则i1必须是具有最大日期的行invoice_id.

这种使用连接的解决方案往往更适合MySQL,这在优化两个GROUP BY和子查询时都很弱.