簡體   English   中英

一個查詢中的多個 SELECT 使用相同的 WITH

[英]Multiple SELECTs in one query using same WITH

此查詢過濾主表中的一些 ID,並將來自其他兩個表的 ID 作為兩個記錄集返回所有數據 abpout:

WITH filteredIds (fid) AS 
(
    SELECT id 
    FROM MasterTable 
    WHERE <somecondition>
)
SELECT * 
FROM Table1 
RIGHT JOIN filteredIds ON (Table1.id = filteredIds.fid);

WITH filteredIds (fid) AS 
(
    SELECT id 
    FROM MasterTable 
    WHERE <somecondition>
)
SELECT * 
FROM Table2 
RIGHT JOIN filteredIds ON (Table2.id = filteredIds.fid);

到目前為止,這是可行的,但最好只有一個 WITH 子句,因為條件總是相同的。 此外,條件通常是手動編寫的,因為它用於收集一些診斷數據。

但是這個

WITH filteredIds (fid) AS 
(
    SELECT id 
    FROM MasterTable 
    WHERE <somecondition>
)
SELECT * 
FROM Table1 
RIGHT JOIN filteredIds ON (Table1.id = filteredIds.fid);

SELECT * 
FROM Table2 
RIGHT JOIN filteredIds ON (Table2.id = filteredIds.fid);

不起作用,SQL 服務器在最后一個查詢中聲稱它不知道filteredIds

我是否監督了某些事情,或者它不是那樣工作的? 我想替代方案將是一個臨時表。

一旦在查詢中使用了 CTE,就不能在另一個查詢中重用它。 據我所知,沒有直接的解決方法。 最接近您想要的可能是創建一個真正的臨時表:

CREATE TABLE #temp (fid int);
INSERT INTO #temp (fid)
SELECT id FROM MasterTable WHERE <somecondition>;

然后,您可以直接重用臨時表:

SELECT * FROM Table1 a RIGHT JOIN #temp b ON a.id = b.fid;
SELECT * FROM Table2 a RIGHT JOIN #temp b ON a.id = b.fid;

你不能用 CTE 做你想做的事。 CTE 在定義它的查詢之外不存在。

我認為最接近您想要的東西稱為“視圖”。

CREATE VIEW filteredIds
AS
SELECT id AS fid
FROM MasterTable 
WHERE <somecondition>
;

現在您可以在許多其他查詢中使用該視圖。

SELECT * 
FROM Table1 
RIGHT JOIN filteredIds ON (Table1.id = filteredIds.fid);

SELECT * 
FROM Table2 
RIGHT JOIN filteredIds ON (Table2.id = filteredIds.fid);

此外,在 SQL 服務器中,它的工作方式與 CTE 完全相同,因為過濾的 ID 列表沒有具體化,引擎將優化引用視圖的整個查詢。 它將視圖定義內聯到外部/主查詢中,就像您在一個大查詢中編寫所有內容一樣。 就像它對 CTE 所做的那樣。

使用臨時表,您可以將此臨時結果顯式寫入磁盤並將其讀回。

在某些情況下它可能會更好,在某些情況下則不然。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM