如何使用两个派生的 table 创建一个通用 table 表达式

How do I create a common table expression with two derived tables

所以我尝试用两个派生的 table 创建这个 CTE。我的第一个导出table会显示帐号,500范围内的帐号的账户说明。 CTE 中的第二个派生 table - 应列出发票总额大于 1000 的帐号、发票总额和发票 ID。

现在我开始分别创建这两个 table 以确保我知道我在做什么。他们是这样工作的:

SELECT AccountNo, 
    AccountDescription
FROM Accounts
WHERE AccountNo BETWEEN 500 and 599

SELECT Accounts.AccountNo, 
    Invoices.InvoiceTotal, 
    Invoices.InvoiceID
FROM Accounts 
    JOIN InvoiceLineItems
        ON Accounts.AccountNo = InvoiceLineItems.AccountNo
    JOIN Invoices
        ON InvoiceLineItems.InvoiceID = Invoices.InvoiceID
WHERE Invoices.InvoiceTotal >= 1000

现在,当我尝试将它们变成 CTE 时,我最好的尝试是这样的:

WITH Accounts500to599 AS
(SELECT AccountNo, 
    AccountDescription
FROM Accounts
WHERE AccountNo BETWEEN 500 and 599
ORDER BY Accounts.AccountNo),

InvoicesAbove1000 AS 
(SELECT Accounts.AccountNo, 
    Invoices.InvoiceTotal, 
    Invoices.InvoiceID
FROM Accounts 
    JOIN InvoiceLineItems
        ON Accounts.AccountNo = InvoiceLineItems.AccountNo
    JOIN Invoices
        ON InvoiceLineItems.InvoiceID = Invoices.InvoiceID
WHERE Invoices.InvoiceTotal >= 1000
ORDER BY Accounts.AccountNo)

现在我的最终目标是显示发票大于平均发票总额的帐户,这应该很简单,但是在创建这些 CTE 时我还有很多东西要学。

如有任何建议,我们将不胜感激。谢谢。

像对待任何其他 table(或视图)一样对待 CTE。它创建一个虚拟 table 供使用。

例如,在你上面,你可以做

WITH Accounts500to599 AS
(SELECT AccountNo, 
    AccountDescription
FROM Accounts
WHERE AccountNo BETWEEN 500 and 599
-- ORDER BY Accounts.AccountNo -- Note - removed the order by
),

InvoicesAbove1000 AS 
(SELECT Accounts.AccountNo, 
    Invoices.InvoiceTotal, 
    Invoices.InvoiceID
FROM Accounts 
    JOIN InvoiceLineItems
        ON Accounts.AccountNo = InvoiceLineItems.AccountNo
    JOIN Invoices
        ON InvoiceLineItems.InvoiceID = Invoices.InvoiceID
WHERE Invoices.InvoiceTotal >= 1000
--ORDER BY Accounts.AccountNo   -- Note - removed the order by
)

SELECT A.AccountNo, A.AccountDescription, AVG(I.InvoiceTotal) AS AvgInvoiceTotal
FROM   Accounts500to599 A
       INNER JOIN InvoicesAbove1000 I ON A.AccountNo = I.AccountNo
GROUP BY A.AccountNo, A.AccountDescription

这没有回答您的 'invoices greater than average',因为当您已经排除发票 < 1000 美元时,这实际上意味着什么,但上面给出了如何使用它们的示例。

请注意,数据的顺序无关紧要(就像正常的 tables 一样)- 因此我在 CTE 中注释掉了 ORDER BY 子句。

传统的 CTE 在功能上也等同于 FROM 子句中的子查询 - 所以上面的内容类似于

SELECT A.AccountNo, A.AccountDescription, AVG(I.InvoiceTotal) AS AvgInvoiceTotal
FROM   (SELECT AccountNo, 
               AccountDescription
        FROM Accounts
        WHERE AccountNo BETWEEN 500 and 599
       ) A
       INNER JOIN 
      (SELECT Accounts.AccountNo, 
          Invoices.InvoiceTotal, 
         Invoices.InvoiceID
       FROM Accounts 
           JOIN InvoiceLineItems
                ON Accounts.AccountNo = InvoiceLineItems.AccountNo
           JOIN Invoices
                ON InvoiceLineItems.InvoiceID = Invoices.InvoiceID
      WHERE Invoices.InvoiceTotal >= 1000
    ) I ON A.AccountNo = I.AccountNo
GROUP BY A.AccountNo, A.AccountDescription

作为对 seanb 答案的一些扩展,以下是您可以尝试使发票高于发票平均值的方法。看看 WHERE.

;WITH Accounts500to599 AS (
    SELECT
        AccountNo, 
        AccountDescription
    FROM AS Accounts
    WHERE
        AccountNo BETWEEN 500 and 599
),
InvoicesAbove1000 AS (
    SELECT
        Accounts.AccountNo, 
        Invoices.InvoiceTotal, 
        Invoices.InvoiceID
    FROM Accounts 
        JOIN InvoiceLineItems
            ON Accounts.AccountNo = InvoiceLineItems.AccountNo
        JOIN Invoices
            ON InvoiceLineItems.InvoiceID = Invoices.InvoiceID
    WHERE 
        Invoices.InvoiceTotal >= 1000
)
SELECT
    Accounts500to599.AccountNo,
    Accounts500to599.AccountDescription,
    InvoicesAbove1000.InvoiceID,
    InvoicesAbove1000.InvoiceTotal
FROM Accounts500to599
INNER JOIN InvoicesAbove1000
    ON Accounts500to599.AccountNo = InvoicesAbove1000.AccountNo
WHERE InvoicesAbove1000.InvoiceTotal > (
    
    SELECT 
        AVG( InvoiceTotal )
    FROM Accounts AS a
    INNER JOIN InvoiceLineItems l
        ON a.AccountNo = l.AccountNo
    INNER JOIN Invoices i
        ON l.InvoiceID = i.InvoiceID
    WHERE
        a.AccountNo BETWEEN 500 AND 599
        AND i.InvoiceTotal > 1000

)
ORDER BY
    Accounts500to599.AccountNo;