如何使用两个派生的 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;
所以我尝试用两个派生的 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;