基于通用计算值的SQL连接

时间:2015-05-11 16:21:32

标签: sql sql-server

使用SQL Server 2012.从具有非重叠键值的两个单独表中查询数据。我能够使用CASE语句计算公共密钥,该语句采用以下形式:

查询#1:

select 
   "Region" = case 
                 when Facility = 100 then Region = 'North'
                 when Facility = 200 then Region = 'South'
                 when Facility = 300 then Region = 'Midwest'
                 else Null 
              end, 
   Other_Variable_1, Other_Variable_2, ...
from 
   Data1

查询#2:

select 
   "Region" = case 
                 when Facility = 63 then Region = 'North'
                 when Facility = 67 then Region = 'South"
                 when Facility = 89 then Region = 'Midwest'
                 else Null 
              end, 
   Other_Variable_A, Other_Variable_A, ...
from 
   Data2

我尝试通过在两个JOIN语句上运行CASE语句来链接这两个查询,如下所示:

select 
    a.Other_Variable_1, b.Other_Variable_B
from 
    Data1 a
inner join 
    Data2 b on (case
                   when a.Facility = 100 then Region = 'North'
                   when a.Facility = 200 then Region = 'South'
                   when a.Facility = 300 then Region = 'Midwest'
                   else Null 
                end) = (case
                           when b.Facility = 63 then Region = 'North'
                           when b.Facility = 67 then Region = 'South"
                           when b.Facility = 89 then Region = 'Midwest'
                           else Null 
                         end)

在我放弃之前,查询运行了一个多小时。有没有更好的方法来连接两个case语句而不发布两个单独的表然后运行第三个查询?

2 个答案:

答案 0 :(得分:1)

我知道你不想要额外的牌桌。我只是想和你分享我在同一案件中的经历。此方法更灵活,用户可以更改Facility和Region之间的映射。我们必须使用计算值连接两个表(1000万行)。我们解决了性能问题。

1.添加1"地区"每个表的列
2.每晚都会有数据处理,用户通过MDS根据指定值更新这些列(我假设只有用户知道设施和区域之间的关系)

create table Data1_Mapping_Facility_Region
(
    Facility int,
    Region nvarchar(60)
)
create index IX_Data1_Mapping_Facility_Region_Facility on Data1 (Facility) include (region)

create table Data2_Mapping_Facility_Region
(
    Facility int,
    Region nvarchar(60)
)
create index IX_Data2_Mapping_Facility_Region_Facility on Data2 (Facility) include (region)

insert into Data1_Mapping_Facility_Region values(100, 'North'), (200, 'South'), (300, 'Midwest')
insert into Data2_Mapping_Facility_Region values(63, 'North'), (67, 'South'), (89, 'Midwest')

Mapping_Data1_Facility_Region

100  'North'
200  'South'
300  'Midwest'

Mapping_Data2_Facility_Region

63   'North'
67   'South'
89   'Midwest'

为Data1和Data2创建索引

create index IX_Data1_Region on Data1 (Region) include (Other_Variable_1)
create index IX_Data2_Region on Data2 (Region) include (Other_Variable_B)

更新Data1和Data2

update  data
set     data.Region = map.Region
from    Data1 data
            inner join Data1_Mapping_Facility_Region map
            on data.Facility = map.Facility

update  data
set     data.Region = map.Region
from    Data2 data
            inner join Data2_Mapping_Facility_Region map
            on data.Facility = map.Facility

将查询更改为

select a.Other_Variable_1, b.Other_Variable_B
from   Data1 a
       inner join Data2 b on a.Region = b.Region

比较查询计划 enter image description here

答案 1 :(得分:0)

是的,尝试在没有CASE语句的情况下完全执行此操作并直接将值映射到彼此:

select a.Other_Variable_1, b.Other_Variable_B
from Data1 a
inner join Data2 b
on (a.Facility = 100 and b.Facility = 63)
or (a.Facility = 200 and b.Facility = 67)
or (a.Facility = 300 and b.Facility = 89)

接下来,确保没有丢失主键 - 我觉得这就是这种情况。否则,您将在表格中获得类似于笛卡尔积的数据集连接。