Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CTE,Temp table and table variable

Can any one please tell me where to use CTE, temp table and table variable?

I read about their differences but i'm confused with their usage. please help.

Thanks.

like image 541
SQLnewbe Avatar asked Aug 17 '15 07:08

SQLnewbe


People also ask

What is the difference between CTE temp table and table variable?

Temp Tables are physically created in the tempdb database. These tables act as the normal table and also can have constraints, an index like normal tables. CTE is a named temporary result set which is used to manipulate the complex sub-queries data. This exists for the scope of a statement.

Which is faster CTE or temp table or table variable?

This biggest difference is that a CTE can only be used in the current query scope whereas a temporary table or table variable can exist for the entire duration of the session allowing you to perform many different DML operations against them.

What is the difference between CTE and temp table which one is better?

Probably the biggest difference between a CTE and a temp table, is that the CTE has an execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement. Essentially you can't reuse the CTE, like you can with temp tables.

Is table variable better than temp table?

Assuming you follow the basic rules-of-engagement, then you should consider table variables as a first choice when working with relatively small data sets. They are easier to work with and they trigger fewer recompiles in the routines in which they're used, compared to using temporary tables.


1 Answers

You can use a CTE in place of a sub query or when you need recursivity.

The CTE is only available during the SQL statement which includes it. Preceding and following statements won't have access to it and won't see it. It behave like a subquery but can be used several time in the following select/update.

This query with sub query with a sub query used twice:

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

Could be replaced by a 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

This is usefull in this case because the same sub query does not have to be written several times.

Recursive CTE (this is just an example, this should not be SQL Server job's to manipulate string data like this):

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

Recursive CTE can be used to retrieve data in a hierachy.

Table variables

Table variables only exist while the query is being executed. It is visible to all SQL statements after its creation.

You can use them when you need to pass data to a stored procedure or function using a table type parameter:

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

You can also use them when you need to store something which is not too big and does not requiere indexes. You cannot manually create an index although a primary key or a unique constraint in the table declaration will automatically create an index.

There are no statistics created on table variables and you cannot create statistics.

Temp Table

Temp table can be used when you are dealing with a lot more data which will benefit from the creation of indexes and statistics.

In a session, any statement can use or alter the table once it has been created:

create table #temp
Insert into #temp(...) select ... From data
exec procA
exec procB
exec procC

Both ProcA, ProcB and ProcC can select, insert, delete or update data from #temp.

Table #temp will be drop as soon as the user session is closed.

If you wan't to keep the temp table between sessions, you can use a global temp table (##temp). It will be available until it is drop or the server is restarted.

like image 141
Julien Vavasseur Avatar answered Sep 30 '22 12:09

Julien Vavasseur