Sql 在select语句中将联接查询重述为相关子查询

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子句中将联接重写为子查询。我知道select语句中的子查询必须返回一个值,我很难弄清楚如何以合理的方式重写它

以下是原始的join语句:

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