通过子查询中的最大日期来连接三张表
我有三张表,orders、invoices和 invoice lines。
uid OrderNumber product_id product_name quantityOnOrder
1 101 p001 Apple 6
2 102 p002 Pear 20
3 103 p003 Orange 9
id invoiceNumber invoiceDate invoiceNotes carrier trackingReference
1 i600 2026-05-01 Part Supply FedEx 5874563
2 i601 2026-05-28 Part Supply FedEx 7893654
id invoiceNumber product_id purchaseOrderNumber quantityInvoiced
1 i600 p002 102 5
2 i601 p002 102 15
一个简单的JOIN会显示所有数据,对于订单号102,预计会有一条重复的记录。
SELECT *
FROM tbl_fruit_orders
LEFT JOIN tbl_fruit_InvoiceLines ON tbl_fruit_orders.OrderNumber = tbl_fruit_InvoiceLines.purchaseOrderNumber
LEFT JOIN tbl_fruit_invoices ON tbl_fruit_InvoiceLines.invoiceNumber = tbl_fruit_invoices.invoiceNumber
与重复记录不同,我只想看到最近的发票日期。我在Stack Overflow上看到这个后,尝试了以下方法。
SELECT *
FROM tbl_fruit_orders
LEFT JOIN tbl_fruit_InvoiceLines ON tbl_fruit_orders.OrderNumber = tbl_fruit_InvoiceLines.purchaseOrderNumber
LEFT JOIN tbl_fruit_invoices ON tbl_fruit_InvoiceLines.invoiceNumber = tbl_fruit_invoices.invoiceNumber
INNER JOIN (
SELECT purchaseOrderNumber, MAX(invoiceDate) AS invoiceDate
FROM tbl_fruit_orders
LEFT JOIN tbl_fruit_InvoiceLines ON tbl_fruit_orders.OrderNumber = tbl_fruit_InvoiceLines.purchaseOrderNumber
LEFT JOIN tbl_fruit_invoices ON tbl_fruit_InvoiceLines.invoiceNumber = tbl_fruit_invoices.invoiceNumber
GROUP BY purchaseOrderNumber
) AS max USING (purchaseOrderNumber, invoiceDate)
这给出了订单号102的期望输出。但对于没有相关发票明细/发票的订单,则不会显示任何行。
解决方案
问题在于:使用INNER JOIN会丢弃未开具发票的订单——改用LEFT JOIN,并对具有最大发票日期的行进行筛选,或筛选出根本没有发票的订单。
最终结果看起来像:
SELECT *
FROM tbl_fruit_orders
LEFT JOIN tbl_fruit_InvoiceLines
ON tbl_fruit_orders.OrderNumber = tbl_fruit_InvoiceLines.purchaseOrderNumber
LEFT JOIN tbl_fruit_invoices
ON tbl_fruit_InvoiceLines.invoiceNumber = tbl_fruit_invoices.invoiceNumber
LEFT JOIN (
SELECT
il.purchaseOrderNumber,
MAX(i.invoiceDate) AS max_invoiceDate
FROM tbl_fruit_InvoiceLines il
JOIN tbl_fruit_invoices i ON il.invoiceNumber = i.invoiceNumber
GROUP BY il.purchaseOrderNumber
) AS max ON tbl_fruit_orders.OrderNumber = max.purchaseOrderNumber
WHERE tbl_fruit_invoices.invoiceDate = max.max_invoiceDate
OR tbl_fruit_invoices.invoiceDate IS NULL;
第二种获取它的方法是使用ROW_NUMBER(为每个订单的最近发票分配1,然后简单的WHERE条件筛选):
WITH RankedInvoices AS (
SELECT
o.OrderNumber,
o.product_id AS order_product_id,
o.product_name,
o.quantityOnOrder,
il.invoiceNumber,
il.quantityInvoiced,
i.invoiceDate,
i.invoiceNotes,
i.carrier,
i.trackingReference,
ROW_NUMBER() OVER(PARTITION BY o.OrderNumber ORDER BY i.invoiceDate DESC) as rn
FROM tbl_fruit_orders o
LEFT JOIN tbl_fruit_InvoiceLines il ON o.OrderNumber = il.purchaseOrderNumber
LEFT JOIN tbl_fruit_invoices i ON il.invoiceNumber = i.invoiceNumber
)
SELECT *
FROM RankedInvoices
WHERE rn = 1;
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。