从没有笛卡儿积

时间:2016-02-08 09:58:34

标签: sql-server join

我正在尝试创建一个命令,将客户端成员资格的详细信息从一个数据库复制到另一个具有相同结构的数据库。为了问题的目的,我把它简化为最基本的要素,因此要复制的四个项目是到期日期,订阅ID,客户ID和项目ID(这是包含订阅的服务)。 客户在两个基础上都有一个共同的GUID。订阅ID是唯一的long int,在两个base中都应该相同,并且到期日期只是一个日期。到目前为止,这么容易。棘手的部分是每个数据库中的item_id不一定相同。我需要使用where语句从一个映射到另一个,我知道该怎么做。

我的问题是我需要从目标数据库自己的ITEM表(item_0)中选择以获取和插入正确的item_id,当我这样做时,我会返回数千个重复的行。我假设我需要使用连接来避免这种情况,但由于我没有任何意义加入item_0,因此我无法获得任何结果。

insert into DestDB..subscription (expiry_date,id,client_id,item_id)
select 
    sub_1.expiry_date,
    sub_1.id,
    cli_0.id as client_id,
    item_0.id as item_id,
from SourceDB..subscription sub_1,
    DestDB..item item_0,
    DestDB..client cli_0
inner join SourceDB..client cli_1
   on cli_1.[guid] = cli_0.[guid] 
where sub_1.id not in (select id from DestDB..subscription)  
and item_0.id = 
     (select id from DestDB..collectiondetails 
             where service_ID =
              (select id from DestDB..service s_0 where s_0.code = 
                 (select code from SourceDB..service s_1 where s_1.id = 
                    (select service_ID from Source..collectiondetails item_1         where item_1.id = sub_1.item_id)))
             and collection_ID =
               (select id from DestDB..collection col_0
                  where col_0.code = 
                    (select code from SourceDB..collection col_1 where col_1.id =
                       (select collection_ID from SourceDB..collectiondetails item_1 where item_1.id = sub_1.collection_ID)))

     )         

1 个答案:

答案 0 :(得分:0)

我担心更新后的问题更令人困惑。 Select子句中的Where保证仅返回一条记录,还是in而不是=

如果没有规则从匹配列表中识别特定的DestDB..item,那么前一个也应该这样做。似乎item_0似乎完全可以省略:

insert into DestDB..subscription (expiry_date,id,client_id,item_id)
select 
    sub_1.expiry_date,
    sub_1.id,
    cli_0.id as client_id,
    (select Top 1 id from DestDB..collectiondetails   --<- Limit to top 1 only
             where service_ID =
              (select id from DestDB..service s_0 where s_0.code = 
                 (select code from SourceDB..service s_1 where s_1.id = 
                    (select service_ID from SourceDB..collectiondetails item_1 where item_1.id = sub_1.item_id)))
             and collection_ID =
               (select id from DestDB..collection col_0
                  where col_0.code = 
                    (select code from SourceDB..collection col_1 where col_1.id =
                       (select collection_ID from SourceDB..collectiondetails item_1 where item_1.id = sub_1.collection_ID)))
     ) as item_id,
from SourceDB..subscription sub_1,
    DestDB..client cli_0
inner join SourceDB..client cli_1
   on cli_1.[guid] = cli_0.[guid] 
where sub_1.id not in (select id from DestDB..subscription)  

请注意:如果DestDB..item为空,则问题示例语句不会插入任何内容,但这个答案是 - item_id设置为NULL

我个人会尝试在一次交易中将此任务分成两个单独的语句:

  1. 使用NULL item_id插入目标表。
  2. 使用new item_id更新目标表,其中item_id为NULL。
  3. (可选)删除无法找到相应item_id的不需要的记录。