sql-server - 从两个表中选择一个

标签 sql-server

我有2张 table 。

让我们称它们为 Table1Table2 。两个表具有相同的结构和数据类型。
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/

相关文章:

html - TD HTML 标签右对齐

sql - 如何在 Catalyst 中的 DBIx::Class 上设置 sql 选项

sql-server - 检索离线的 SQL Server 数据库的文件列表

sql - 生产BoM爆破演练幻影BoM

c# - 单元测试插入/更新/删除

sql - 稀疏列大小限制解决方法

sql - 外键约束是否自动禁止空值?

sql-server - 仅选择 "customer"的所有行都具有相同状态的位置?

sql-server - 使用 TYPE(在 sql server 2008 中)命令将缓冲区大小限制为 255

php 无法连接到 sql server 2008(使用 pdo dblib)