CTE、温度 table 和 table 变量
CTE,Temp table and table variable
谁能告诉我在哪里使用 CTE
、temp table
和 table variable
?
我了解了它们的区别,但对它们的用法感到困惑。请帮忙
谢谢。
您可以使用 CTE 代替子查询或当您需要递归时。
CTE 仅在包含它的 SQL 语句期间可用。前面和后面的语句将无法访问它,也不会看到它。它的行为类似于子查询,但可以在以下 select/update.
中多次使用
这个带有子查询的查询使用了两次:
Select D.* From D
Inner Join (
Select id value, date From A
Inner Join B on A.data < B.date
Inner Join C on C.data > B.date
) CTE a c1 on c1.id = D.id+1
Inner Join (
Select id value, date From A
Inner Join B on A.data < B.date
Inner Join C on C.data > B.date
) as c2 on c2.id = D.id-1
可以用 CTE 代替:
; with CTE as (
Select id value, date From A
Inner Join B on A.data < B.date
Inner Join C on C.data > B.date
)
Select D.* From D
Inner Join CTE as c1 on c1.id = D.id+1
Inner Join CTE as c2 on c2.id = D.id-1
这在这种情况下很有用,因为不必多次编写相同的子查询。
递归 CTE(这只是一个例子,这不应该是 SQL 服务器作业来像这样操作字符串数据):
Declare @data varchar(50) = 'Recursive CTE'
; With list(id, letter) as (
Select 1, SUBSTRING(@data, 1, 1)
Union All
Select id+1, SUBSTRING(@data, id+1, 1) From list
Where id < len(@data)
)
Select * from list
递归 CTE 可用于检索层次结构中的数据。
Table 变量
Table 变量仅在执行查询时存在。它在创建后对所有 SQL 语句可见。
当您需要使用 table 类型参数将数据传递给存储过程或函数时,您可以使用它们:
Create Proc test(
@id int,
@list table_type_list READONLY
)
begin
set nocount on
select * from @list
end
Declare @t table_type_list
Insert into @t(name) values('a'), ('b'), ('c')
Exec test 1, @t
当你需要存储不太大且不需要索引的东西时,你也可以使用它们。
尽管 table 声明中的主键或唯一约束会自动创建索引,但您无法手动创建索引。
table 变量没有创建统计信息,您无法创建统计信息。
温度Table
Temp table 可以在处理大量数据时使用,这将受益于索引和统计信息的创建。
在会话中,任何语句都可以在创建后使用或更改 table:
create table #temp
Insert into #temp(...) select ... From data
exec procA
exec procB
exec procC
ProcA、ProcB 和 ProcC 都可以select、插入、删除或更新来自#temp 的数据。
Table #temp 将在用户会话关闭后立即下降。
如果您不想在会话之间保持温度 table,您可以使用全局温度 table (##temp)。它将一直可用,直到它被删除或服务器重新启动。
谁能告诉我在哪里使用 CTE
、temp table
和 table variable
?
我了解了它们的区别,但对它们的用法感到困惑。请帮忙
谢谢。
您可以使用 CTE 代替子查询或当您需要递归时。
CTE 仅在包含它的 SQL 语句期间可用。前面和后面的语句将无法访问它,也不会看到它。它的行为类似于子查询,但可以在以下 select/update.
中多次使用这个带有子查询的查询使用了两次:
Select D.* From D
Inner Join (
Select id value, date From A
Inner Join B on A.data < B.date
Inner Join C on C.data > B.date
) CTE a c1 on c1.id = D.id+1
Inner Join (
Select id value, date From A
Inner Join B on A.data < B.date
Inner Join C on C.data > B.date
) as c2 on c2.id = D.id-1
可以用 CTE 代替:
; with CTE as (
Select id value, date From A
Inner Join B on A.data < B.date
Inner Join C on C.data > B.date
)
Select D.* From D
Inner Join CTE as c1 on c1.id = D.id+1
Inner Join CTE as c2 on c2.id = D.id-1
这在这种情况下很有用,因为不必多次编写相同的子查询。
递归 CTE(这只是一个例子,这不应该是 SQL 服务器作业来像这样操作字符串数据):
Declare @data varchar(50) = 'Recursive CTE'
; With list(id, letter) as (
Select 1, SUBSTRING(@data, 1, 1)
Union All
Select id+1, SUBSTRING(@data, id+1, 1) From list
Where id < len(@data)
)
Select * from list
递归 CTE 可用于检索层次结构中的数据。
Table 变量
Table 变量仅在执行查询时存在。它在创建后对所有 SQL 语句可见。
当您需要使用 table 类型参数将数据传递给存储过程或函数时,您可以使用它们:
Create Proc test(
@id int,
@list table_type_list READONLY
)
begin
set nocount on
select * from @list
end
Declare @t table_type_list
Insert into @t(name) values('a'), ('b'), ('c')
Exec test 1, @t
当你需要存储不太大且不需要索引的东西时,你也可以使用它们。 尽管 table 声明中的主键或唯一约束会自动创建索引,但您无法手动创建索引。
table 变量没有创建统计信息,您无法创建统计信息。
温度Table
Temp table 可以在处理大量数据时使用,这将受益于索引和统计信息的创建。
在会话中,任何语句都可以在创建后使用或更改 table:
create table #temp
Insert into #temp(...) select ... From data
exec procA
exec procB
exec procC
ProcA、ProcB 和 ProcC 都可以select、插入、删除或更新来自#temp 的数据。
Table #temp 将在用户会话关闭后立即下降。
如果您不想在会话之间保持温度 table,您可以使用全局温度 table (##temp)。它将一直可用,直到它被删除或服务器重新启动。