2

作为练习作业,我希望将连接重写为 select 子句中的子查询。我知道 select 语句中的子查询必须返回一个值,我很难弄清楚如何以一种有意义的方式重写它。

这是原始的连接语句:

SELECT InvoiceNumber, InvoiceDate, InvoiceLineItemAmount
FROM Invoices JOIN InvoiceLineItems
  ON Invoices.InvoiceID = Invoicelineitems.InvoiceID
WHERE VendorID = 122
ORDER BY InvoiceDate

任何提示或帮助将不胜感激!

4

3 回答 3

1

我的提示是在您的主查询中使用 InvoiceLineItems,在子查询中使用 Invoices。这将增加您的子查询恰好返回一行的可能性。

于 2013-02-16T23:04:15.847 回答
1

ON您只需将条件放在WHERE子查询的子句中,而不是使用子句。

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。但是,在不知道您的架构约束的情况下,您可能会遇到同样的returns more than one value问题。

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

最后,这一切都取决于您的要求。

于 2013-02-16T23:05:39.370 回答
0

如果在子查询中多于一行,则需要TOP子句

SELECT InvoiceNumber, InvoiceDate, 
 (
  SELECT InvoiceLineItemAmount
  FROM InvoiceLineItems
  WHERE Invoices.InvoiceID = Invoicelineitems.InvoiceID
  ) AS InvoiceLineItemAmount 
FROM Invoices
WHERE VendorID = 122
ORDER BY InvoiceDate
于 2013-02-16T23:04:22.657 回答