我有2张 table 。
让我们称它们为 Table1
和 Table2
。两个表具有相同的结构和数据类型。Table1
是交易表,Table2
是历史数据表。
我需要做这样的事情:
Select * from case when 'transnational' then Table1 else Table2 end
但是,我不想使用 2
select
语句来执行此操作。我可以为此使用
CASE
语句吗?
最佳答案
好问题!我们试试看:
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
极简联盟所有解决方案将是:
Declare @tabindex bit = 0;
Select * From tab0 Where @tabindex = 1 Union All
Select * From tab1 Where @tabindex = 0;
执行计划指示两个表扫描和过滤器与一个串联。
这还不够好。让我们看看如果条件不正确,优化器是否真的可以跳过表处理:
Select * From tab0 Where 1 = 1 Union All
Select * From tab1 Where 1 = 0
GO
...和执行计划指示 一次 表扫描和一次计算标量,成本为 0%。因此,技术上优化器 可以 做到这一点。问题是任何涉及变量的条件都会针对表进行评估,从而导致表扫描。所以我们只需要在
Select
之前评估条件。嗯,也有一个答案,名称为 表值函数 :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;
现在,如果我们运行
Select * From tab(1);
或 Select * From tab(0);
执行计划将仅指示一次表扫描、一个表值函数和一个序列,两者的成本均为 0%。所以答案是 是的,我们可以在表值函数 中使用
CASE
语句。在 Shnugo 评论后更新 。该功能实际上可以改进:
Create Function tab (@tabNo int)
Returns Table
As
Return
Select * From tab0 Where @tabNo = 0 Union All
Select * From tab1 Where @tabNo = 1;
GO
现在
Select * From tab(1);
或 Select * From tab(0);
只产生一次表扫描和一次计算标量。显然,对于已编译的函数,优化器知道不要在表中查找参数变量。
关于sql-server - 从两个表中选择一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36857438/