繁体   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