在同一查询中多次调用CTE

时间:2013-08-07 04:35:44

标签: sql sql-server tsql

我有一个相当复杂的查询,其中包含多个CTE,但其他所有CTE都有一个主CTE,这是否会导致主CTE多次执行?

2 个答案:

答案 0 :(得分:2)

您可以使用CROSS JOIN:

SELECT 
    AVG(CASE WHEN instructorID = @instructorID THEN score END) InstructorSemesterAverage,
    STDEVP(CASE WHEN instructorID = @instructorID THEN score END) InstructorSemesterSTDeviation,
    AVG(CASE WHEN subjectCode = @subjectCode THEN score END) DepartmentSemesterAverage, 
    STDEVP(CASE WHEN subjectCode = @subjectCode THEN score END) DepartmentSemesterSTDeviation, 
    AVG(CASE WHEN bannerCRN=@CRN AND Q.year = @year AND semester = @semester THEN score END) ClassScore,
    STDEVP(CASE WHEN bannerCRN=@CRN AND Q.year = @year AND semester = @semester THEN score END) ClassSTDeviation,
    (SELECT DecTile FROM cteNtile WHERE instructorID = @instructorID)*10 DecTile,
    X.DepartmentClassFiveYearAverage AS DepartmentClassFiveYearAverage,
    X.DepartmentClassFiveYearSTDeviation AS DepartmentClassFiveYearSTDeviation,
    X.InstructorClassFiveYearAverage AS InstructorClassFiveYearAverage,
    X.InstructorClassFiveYearSTDeviation AS InstructorClassFiveYearSTDeviation
FROM 
    cteMain Q CROSS JOIN cteFiveYear X

这将阻止Number of Executions的多次执行(针对实际执行计划,请参阅cteFiveYear属性)。

示例:如果执行此查询

SELECT  h.ProductID,h.StandardCost,
        x.AvgPrice
FROM    Production.ProductCostHistory h
CROSS JOIN (
    SELECT  AVG(p.ListPrice) AvgPrice
    FROM    Production.Product p
) x

使用AdventureWorks2008R2数据库然后实际的执行计划 enter image description here

答案 1 :(得分:1)

看看下面的

DECLARE @Table TABLE(
        ID INT,
        Val VARCHAR(50),
        TypeID INT
)

DECLARE @TableTypes TABLE(
        TypeID INT,
        TypeName VARCHAR(50)
)

;WITh Vals AS (
        SELECT  *
        FROm    @Table
        WHERE   ID > 10
)
, UsingVals1 AS (
        SELECT  v.*,
                tt.TypeName
        FROm    Vals v INNER JOIN
                @TableTypes tt ON v.TypeID = tt.TypeID
)
, UsingVals2 AS (
        SELECT  v.*,
                tt.TypeName
        FROm    Vals v INNER JOIN
                @TableTypes tt ON v.TypeID = tt.TypeID
        WHERE   tt.TypeName LIKE '%%'
)
SELECT  *
FROM    UsingVals1
UNION 
SELECT  *
FROM    UsingVals2

然后在此SQL Fiddle DEMO

您将从执行计划中注意到Vals CTE部分执行了两次。

也许还要看看How many times the T-SQL inside the CTE is executed?