Reputation: 570
I have 2 tables.
Lets call them Table1
and Table2
. Both tables have the same structure and data type.
Table1
is a transaction table and Table2
is a historical data table.
I need to do something like this:
Select * from case when 'transnational' then Table1 else Table2 end
I do not want to use 2 select
statement to do this however.
Can I use the CASE
statement for this?
Upvotes: 5
Views: 2218
Reputation: 3586
Great question! Let's try:
Create Table tab0 (col int primary key);
Create Table tab1 (col int primary key);
Insert Into tab0 (col) Values (0);
Insert Into tab1 (col) Values (1);
GO
Minimalist Union All solution would be:
Declare @tabindex bit = 0;
Select * From tab0 Where @tabindex = 1 Union All
Select * From tab1 Where @tabindex = 0;
Execution plan indicate two table scans and filters with one concatenation.
That is not good enough. Let's see whether optimizer can actually skip table processing if conditions are not right:
Select * From tab0 Where 1 = 1 Union All
Select * From tab1 Where 1 = 0
GO
... and Execution plan indicate one table scan and one Compute Scalar at cost 0%. So, technically optimizer can do it. The problem is any condition involving variable would get evaluated against the table resulting in a table scan. So we just need to evaluate the condition before Select
. Well, there is an answer to that too by the name of table-valued function:
Create Function tab (@tabNo int)
Returns @RetTab Table (col int)
As
Begin
If @tabNo = 1 Insert Into @RetTab Select * From tab1
Else Insert Into @RetTab Select * From tab0;
Return;
End;
Now if we run Select * From tab(1);
or Select * From tab(0);
Execution plan would indicate just one table scan, one Table Valued Function and one Sequence both costing 0%.
So the answer is yes, we can use CASE
statement in table-valued function.
Update following Shnugo comment. The function can actually be improved:
Create Function tab (@tabNo int)
Returns Table
As
Return
Select * From tab0 Where @tabNo = 0 Union All
Select * From tab1 Where @tabNo = 1;
GO
Now Select * From tab(1);
or Select * From tab(0);
results in one Table Scan and one Compute Scalar only. Apparently with compiled function the optimizer know not to look for the parameter variable in the table.
Upvotes: 2