Sql 在select语句中将联接查询重述为相关子查询
作为实践作业,我希望在select子句中将联接重写为子查询。我知道select语句中的子查询必须返回一个值,我很难弄清楚如何以合理的方式重写它 以下是原始的join语句:Sql 在select语句中将联接查询重述为相关子查询,sql,sql-server-2008,Sql,Sql Server 2008,作为实践作业,我希望在select子句中将联接重写为子查询。我知道select语句中的子查询必须返回一个值,我很难弄清楚如何以合理的方式重写它 以下是原始的join语句: SELECT InvoiceNumber, InvoiceDate, InvoiceLineItemAmount FROM Invoices JOIN InvoiceLineItems ON Invoices.InvoiceID = Invoicelineitems.InvoiceID WHERE VendorID = 1
SELECT InvoiceNumber, InvoiceDate, InvoiceLineItemAmount
FROM Invoices JOIN InvoiceLineItems
ON Invoices.InvoiceID = Invoicelineitems.InvoiceID
WHERE VendorID = 122
ORDER BY InvoiceDate
任何提示或帮助将不胜感激 我的建议是在主查询中包含InvoiceLineItems,在子查询中包含Invoices。这将增加子查询只返回一行的可能性。如果子查询中有多行,则需要子句
您只需将条件放置在子查询的
WHERE
子句中,而不是使用ON
子句
SELECT InvoiceNumber, InvoiceDate,
(SELECT InvoiceLineItemAmount
FROM InvoiceLineItems
WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID)
AS InvoiceLineItemAmount
FROM Invoices
WHERE VendorID = 122
ORDER BY InvoiceDate
如果子查询返回多个值,则有几个选项
您可以抓取TOP 1
SELECT InvoiceNumber, InvoiceDate,
(SELECT TOP 1 InvoiceLineItemAmount
FROM InvoiceLineItems
WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID)
AS InvoiceLineItemAmount
FROM Invoices
WHERE VendorID = 122
ORDER BY InvoiceDate
您可以使用聚合函数
SELECT InvoiceNumber, InvoiceDate,
(SELECT MAX(InvoiceLineItemAmount)
FROM InvoiceLineItems
WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID)
AS InvoiceLineItemAmount
FROM Invoices
WHERE VendorID = 122
ORDER BY InvoiceDate
或者可以使用XML连接结果
SELECT InvoiceNumber, InvoiceDate,
STUFF((
SELECT ', ' + LTRIM(InvoiceLineItemAmount)
FROM InvoiceLineItems
WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID
FOR XML PATH('')),
1, 2, '') AS InvoiceLineItemAmount
FROM Invoices
WHERE VendorID = 122
ORDER BY InvoiceDate
或者,对于@MartinSmith,您可以将InvoiceLineItems的关系反转并挂起。但是,在不知道模式约束的情况下,可能会遇到相同的返回多个值的问题
SELECT (SELECT InvoiceNumber
FROM InvoiceLineItems
WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID)
AS InvoiceNumber,
(SELECT InvoiceDate
FROM InvoiceLineItems
WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID)
AS InvoiceDate
InvoiceLineItemAmount
FROM InvoiceLineItems
WHERE VendorID = 122
ORDER BY InvoiceDate
最后,这完全取决于您的需求。表的定义是什么?我们需要猜测目前哪些列属于哪些表以及基数。+1假设关系为1发票到许多行项目,这将起作用。发票中带有的答案不会出现。想再看看你写的吗?请特别注意“join”一词后面的内容。有很多选项,但没有一个选项将InvoiceLineItems中的作为主查询,将Invoices中的作为相关子查询。通过这种方式,假设InvoiceID
是Invoices
的主键,并且有一个外键阻止孤立行项目,则只能有一个匹配行。+1我认为我们可以有根据地猜测,invoicesid
表不太可能有多行具有相同的InvoiceID
这是一个很好的假设,然而,我在野外看到了更疯狂的事情。
SELECT (SELECT InvoiceNumber
FROM InvoiceLineItems
WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID)
AS InvoiceNumber,
(SELECT InvoiceDate
FROM InvoiceLineItems
WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID)
AS InvoiceDate
InvoiceLineItemAmount
FROM InvoiceLineItems
WHERE VendorID = 122
ORDER BY InvoiceDate