使用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
。
答案 0 :(得分: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;
说明:对于每一行i1
,尝试查找具有相同i2
和更长日期的行invoice_id
。如果没有找到(即i2
因外部联接而全部为空),则i1
必须是invoice_id
日期最长的行。
使用join的此解决方案往往更适合MySQL,在优化GROUP BY
和子查询时,它很弱。
答案 1 :(得分: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
答案 2 :(得分:2)
几乎就像你用英语说的那样
“获取最新发票日期的发票”
Select * From invoice_items
Where invoice_date =
(Select Max(invoice_date)
From invoice_items)
但我认为你的架构出了问题。由于存在多个具有相同Invoice_Id的行,因此这看起来像发票明细或发票行项目表(不是发票表)。如果是这样,同一发票中的每个行项目如何具有不同的InvoiceDates“?如果这些不同,则它们不是发票日期,它们是发票明细日期,(无论这意味着什么),并且应该标记为如此。< / p>
答案 3 :(得分: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
答案 4 :(得分: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