我一直在制作一部剧本上遇到困难,希望能够深入了解我做错了什么
问题:
使用相关子查询返回每个供应商的发票,代表供应商最早的发票(具有最早日期的发票)。每行应包括以下四列:供应商名称,发票编号,发票日期和发票总额。
我的脚本:
SELECT DISTINCT Vendor_Name,
Invoice_number AS OLDEST_INVOICE,
Invoice_date,
invoice_total
FROM Vendors v
JOIN Invoices i ON v.vendor_id = i.vendor_id
WHERE invoice_date IN (
SELECT DISTINCT MIN(invoice_date)
FROM invoices i
JOIN vendors v ON i.vendor_id = v.vendor_id
GROUP BY v.vendor_name
)
ORDER BY Invoice_Date;
目前,我的代码返回了太多结果,基本上我无法确定invoice_numbers只会在最短的日期返回。
答案 0 :(得分:1)
您需要将联接限制为特定供应商的那些发票,并且具有最早的日期... 你不知道发票表是否有代理PK ......如果没有,请尝试:
SELECT
v.Vendor_Name,
i.Invoice_number as OLDEST_INVOICE,
i.Invoice_date,
i.invoice_total
FROM Vendors v
JOIN Invoices i
ON i.vendor_id = v.vendor_id
And i.invoice_date =
(Select MIN(invoice_date)
From Invoices
Where vendor_id = v.Vendor_Id)
ORDER BY i.Invoice_Date;
如果发票表有代理PK,请说InvoiceId,那么试试这个:
SELECT
v.Vendor_Name,
i.Invoice_number as OLDEST_INVOICE,
i.Invoice_date,
i.invoice_total
FROM Vendors v
JOIN Invoices i
ON i.InvoiceId =
(Select InvoiceId
From Invoices
Where vendor_id = v.Vendor_Id
And Invoice_Date =
(Select Min(Invoice_Date)
From Invoices
vendor_id = v.Vendor_Id))
ORDER BY i.Invoice_Date;
前者仅使用一个子查询,但后者更真实(更清楚地表达)查询意图的意图。
答案 1 :(得分:0)
我建议您不要在WHERE
子句中使用子查询,而是在内部JOIN
中使用派生表。
SELECT
v.Vendor_Name,
i.Invoice_number as OLDEST_INVOICE,
i.Invoice_date,
i.invoice_total
FROM Vendors v
JOIN Invoices i ON v.vendor_id = i.vendor_id
JOIN (SELECT
i2.vendor_id,
MIN(i2.invoice_date) AS min_invoice_date
FROM invoices i2
GROUP BY i2.vendor_id) minv
ON minv.vendor_id = v.vendor_id
AND minv.min_invoice_date = i.invoice_date
ORDER BY i.Invoice_Date;
答案 2 :(得分:0)
根据您的平台,可以更简洁地编写(使用分析窗口函数更容易理解):
http://my.safaribooksonline.com/book/databases/sql/0596004818/sql-functions/sqlnut2-chp-4-sect-3