3

使用 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

使用 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

请注意,查询似乎得到了MAX(invoice_date)正确的结果,但id返回的 (3235) 不是id包含MAX(invoice_date)(3295) 的记录,而是id初始查询中的第一条记录。

如何重构此查询以给我包含的整个记录MAX(invoice_date)​​?

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

4

5 回答 5

7

这是经常重复的“greatest-n-per-group”问题。

这是我在 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;

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

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

于 2009-12-18T22:29:00.260 回答
3

我假设由于表名是 invoice_items 给定发票会有多行,所以你可能应该使用这样的东西:

SELECT * FROM invoice_items 
WHERE invoice_date IN (SELECT MAX(invoice_date) FROM invoice_items)

如果您不关心具有相同发票日期的两条记录,您可以这样做:

SELECT * FROM invoice_items
ORDER BY invoice_date DESC
LIMIT 1
于 2009-12-18T22:02:23.507 回答
2

和你用英语说的完全一样

“给我提供最新发票日期的发票”

Select * From invoice_items
Where invoice_date =
   (Select Max(invoice_date)
    From invoice_items)

但我认为你的架构有问题。由于有多个行具有相同的 Invoice_Id,因此这看起来像发票详细信息或发票行项目表(而不是发票表)。如果是这样,同一张发票中的每个行项目怎么会有不同的 InvoiceDates”?如果这些不同,那么它们不是发票日期,它们是发票明细日期,(无论这意味着什么)并且应该这样标记..

于 2009-12-18T22:06:47.620 回答
2

这是我的尝试:

SELECT t1.*
FROM INVOICE_ITEMS t1,
   (SELECT INVOICE_ID, MAX(INVOICE_DATE) as invoice_date2
      FROM INVOICE_ITEMS
     GROUP BY INVOICE_ID) t2
WHERE t1.invoice_id = t2.invoice_id
AND t1.invoice_date = t2.invoice_date2
于 2009-12-18T22:51:03.437 回答
0
SELECT * 
FROM invoice_items
WHERE lot = 1047
ORDER BY invoice_date desc LIMIT 1

或者如果您的 id 是您的主键并且一直在增长,则更好

SELECT * 
FROM invoice_items
WHERE lot = 1047
ORDER BY id desc LIMIT 1
于 2009-12-18T22:03:14.273 回答