Ket*_*tan 12 sql-server cte sql-server-2014
如在 MSDN 上使用公用表表达式中所示,您可以将 CTE 定义为:
WITH expression_name [ ( column_name [,...n] ) ]
AS
( CTE_query_definition )
Run Code Online (Sandbox Code Playgroud)
并使用它:
SELECT <column_list> FROM expression_name;
Run Code Online (Sandbox Code Playgroud)
假设我有以下 2 个 CTE
with cte1 as(
select name from Table1
)
with cte2(name) as(
select name from Table1
)
Run Code Online (Sandbox Code Playgroud)
一个查询为两个 CTE 输出相同的结果,因为内部查询是相同的。这两者之间的唯一区别是cte2(name)
在其声明中定义了列名( )。
当我执行两个 CTE 时,我看不到执行计划有任何不同。
我只是想知道:
Sha*_*eis 29
您几乎已经找到了其中一个问题的答案。
在MSDN页面中,您的引用后面有一行直接解释了这一点:
CTE 的基本语法结构是:
WITH expression_name [ ( column_name [,...n] ) ]
作为
( CTE_query_definition )
仅当查询定义中提供了所有结果列的不同名称时,列名列表才是可选的。
(强调)
这意味着您需要在以下几种情况下指定列名:
这会起作用:
WITH [test_table] ([NoName], [CAST], [Function])
AS
(
SELECT
1
, CAST('1' AS CHAR(1))
, dbo.CastToChar(1)
)
SELECT * FROM [test_table];
Run Code Online (Sandbox Code Playgroud)就像这样:
WITH [test_table]
AS
(
SELECT
1 as [NoName]
, CAST('1' AS CHAR(1)) as [CAST]
, dbo.CastToChar(1) as [Function]
)
SELECT * FROM [test_table];
Run Code Online (Sandbox Code Playgroud)但这不会,因为它没有列的不同名称:
WITH [test_table]
AS
(
SELECT
1
, CAST('1' AS CHAR(1))
, dbo.CastToChar(1)
)
SELECT * FROM [test_table];
Run Code Online (Sandbox Code Playgroud)Han*_*non 12
有趣的是,我更喜欢在 CTE 内而不是在WITH CTE (xxx) AS
1子句内命名列,因为您永远不会无意中将名称与列内容不匹配。
以下面的例子为例:
;WITH MyCTE (x, y)
AS
(
SELECT mt.y
, mt.x
FROM MySchema.MyTable mt
)
SELECT MyCTE.x
, MyCTE.y
FROM MyCTE;
Run Code Online (Sandbox Code Playgroud)
这显示什么?它显示的内容y
的标题栏下x
,与内容x
标题下的列y
。
有了这个认识,我从不在(xxx) AS
子句中指定列名,而是这样做:
;WITH MyCTE
AS
(
SELECT Alias1 = mt.y
, Alias2 = mt.x
FROM MySchema.MyTable mt
)
SELECT MyCTE.Alias1
, MyCTE.Alias2
FROM MyCTE;
Run Code Online (Sandbox Code Playgroud)
这消除了对列定义是什么的所有疑问。
在一个完全不相关的旁注上;在引用对象名称时始终指定模式名称,并以分号结束您的语句。
最终,每一列都需要一个有效的名称,您可以通过两种方式分配它:
列列表
;WITH cte (foo)
AS
( select col from tab )
select foo from cte;
Run Code Online (Sandbox Code Playgroud)使用原始列名或别名
;WITH cte
AS
( select col from tab )
select col from cte;
Run Code Online (Sandbox Code Playgroud)当您同时执行别名和列列表时
列列表和别名
;WITH cte (foo, bar)
AS
( select col1 -- not valid in outer Select
col2 as colx -- not valid in outer Select
from tab )
select foo, bar from cte;
Run Code Online (Sandbox Code Playgroud)这类似于视图或派生表的定义,您也可以在其中指定列名列表。
列列表:当您有大量复杂的计算时,更容易找到名称,因为它们不会分散在源代码中。如果你有一个递归的 cte 并且你可以为 #3 中的同一列分配两个不同的名称,那就更容易了。
原始名称/别名:如果您进行计算或想要/必须重命名列,则只需分配别名
归档时间: |
|
查看次数: |
14046 次 |
最近记录: |