27

由于长期使用 SQL2000,我并没有真正接触过公用表表达式。

我在此处 (#4025380)此处 (#4018793)给出的答案与流程背道而驰,因为他们没有使用 CTE。

我很欣赏递归它们是 beez kezez,并且有一些查询可以通过它们的使用大大简化,但是在什么时候它们的使用只是轻浮的?与子查询或联接相比,它们是否具有很大的性能优势?他们真的简化了代码并使其更易于维护吗?

简而言之,什么时候最好使用 CTE 而不是“较少”的语法。

4

4 回答 4

26

在以下情况下,您通常应该在普通子查询上使用 CTE:

  • 您的查询需要递归(如您所述)
  • 子查询很大或很复杂
  • 包含的查询很大或很复杂
  • 重复子查询(或者至少可以通过对一个普通子查询执行不同的简单操作来简化几个子查询)

简而言之,是的,它们确实使查询在使用得当时更具可读性。

于 2010-10-27T20:53:21.270 回答
20

就个人而言,一旦我习惯了使用它们,我认为它们会产生更清晰、更易读的代码。例如,将您的答案与我在#4018793上的答案进行比较。我们基本上做了同样的事情;我用了 CTE 而你没有。

您没有 CTE 的答案:

SELECT
    course,
    section,
    grade,
    gradeCount
FROM
    table
INNER JOIN
    (SELECT
        grade,
        Max(gradeCount) as MaxGradeCount
    FROM
        table
    ) MaxGrades
    ON  table.grade = MaxGrades.grade
        AND table.gradeCount = MaxGrades.MaxGradeCount
ORDER BY 
    table.grade

我对 CTE 的回答:

;with cteMaxGradeCount as (
    select 
        grade, 
        max(gradeCount) as MaxGradeCount
    from @Test
    group by grade
)
select 
    t.course, 
    t.SECTION, 
    t.grade, 
    t.gradeCount
from cteMaxGradeCount c
inner join @Test t
    on  c.grade = t.grade
        and c.MaxGradeCount = t.gradeCount
order by t.grade
于 2010-10-27T21:03:34.787 回答
4

它们是语法糖,分层/递归查询除外。

但是,并非所有可以递归完成的事情都应该是 - 通过递归 CTE 生成日期几乎不比游标好 - NUMBERS 表技巧的扩展性要好得多。

于 2010-10-27T20:54:04.910 回答
2

CTE 在递归场景中产生更快的结果。重复使用 CTE 的结果来获得最终结果集。因此,既然您已经在 CTE 中使用了 where 子句或子查询,那么它肯定会显示出性能改进。
参考: http: //msdn.microsoft.com/en-us/library/ms190766 (v=sql.105).aspx

请注意,在许多情况下,临时表的性能也比 CTE 更好,因此您也应该尝试使用临时表。
参考:http ://social.msdn.microsoft.com/Forums/en/transactsql/thread/d040d19d-016e-4a21-bf44-a0359fb3c7fb

于 2012-07-21T14:50:01.013 回答