【问题标题】:SQL Server : Insert statement duplicating non duplicate valuesSQL Server:插入重复非重复值的语句
【发布时间】:2017-02-03 14:05:43
【问题描述】:

我曾多次遇到这种情况,但在测试时并非总是在同一个数据库上发生这种情况。我有两个独立的数据库,我正在合并到一个数据库中,两者的结构完全相同。将记录从一个数据库插入另一个数据库时,我看到目标数据库上存在重复的不同值,但在一个源中仅存在一次,而在目标中不存在。

例子:

DB1..客户

Cust_ID | Last_Name | First_Name | Phone    | Email   | Field1
1       | Smith     | John       | 111-1111 | m@M.com |      

DB2..客户

Cust_ID | Last_Name | First_Name | Phone    | Email   | Field1
1       | Jones     | Steve      | 222-2222 | S@S.com | 
2       | Smith     | Tom        | 333-3333 | S@m.com | 

当我运行查询时:

INSERT INTO DB1..Customer (Last_Name, First_Name, Phone, Email, Field1)
    SELECT
        Last_name, First_Name, Phone, Email, Cust_ID 
    FROM
        DB2..Customer DB2 
    WHERE 
        DB2.Cust_ID NOT IN (SELECT DB2.Cust_ID 
                            FROM DB2..Customer DB2 
                            INNER JOIN DB1..Customer DB1 ON DB1.Last_Name = DB2.Last_Name 
                                                         AND DB1.First_Name = DB2.First_Name 
                                                         AND DB1.Email = DB2.Email)

结果:

DB1..客户

Cust_ID | Last_Name | First_Name | Phone    | Email   | Field1
1       | Smith     | John       | 111-1111 | m@M.com |      
2       | Jones     | Steve      | 222-2222 | S@S.com | 1
3       | Jones     | Steve      | 222-2222 | S@S.com | 1
4       | Jones     | Steve      | 222-2222 | S@S.com | 1
5       | Jones     | Steve      | 222-2222 | S@S.com | 1
6       | Smith     | Tom        | 333-3333 | S@m.com | 2
7       | Smith     | Tom        | 333-3333 | S@m.com | 2
8       | Smith     | Tom        | 333-3333 | S@m.com | 2

当我对具有多个 db2..customer.cust_id 计数的 field1 列进行计数时,我注意到输入了重复的值。因为Cust_ID 是PK 值,所以我的每个查询应该只有一个值流入field1 列。

关于为什么会发生这种情况的任何想法或建议?我上次运行的查询重复了一些项目多达 4 次。在我看来,SQL 在搜索患者的同时也将它们写入目标数据库时陷入了一个循环。

【问题讨论】:

  • SQL Server 未陷入循环。

标签: sql-server database


【解决方案1】:

左连接有点慢,但更容易阅读和做你想做的事。

INSERT INTO DB1..Customer(
  Last_Name
, First_Name
, Phone
, Email
, Field1)
SELECT
  B.Last_name
, B.First_Name
, B.Phone
, B.Email
, B.Cust_ID
FROM
  DB2..Customer B
    LEFT JOIN
    DB1..Customer A ON
  A.Last_Name = B.Last_Name
  AND
  A.First_Name = B.First_Name
  AND
  A.Email = B.Email
  AND
  A.Phone = B.Phone
WHERE A.Cust_ID IS NULL;

【讨论】:

  • 我没有在其中作为第二种方法存在,并解释说它会表现得更好。但是我们不得不假设他从第一天开始就滥用field1,上面有一个唯一索引,并且是相同的数据类型。如果我们必须引用主查询的字段(Last_Name First_NameEmailPhone)来生成WHERE NOT EXISTS (SELECT 1 FROM ... WHERE Last_Name = A.Last_Name ...,NOT EXISTS 的性能不会更好
  • 它在您提供的链接的示例中有效,因为这些是 PK。
【解决方案2】:

您可以尝试将外部查询和子查询中使用的别名更改为不同吗?我手头没有多个实例要测试,但我想知道它是否被解释为相关子查询。

尝试以下查询,它使用 DB1_Inner/DB2_Inner/DB2_Outer 来区分别名:

Insert into DB1..Customer (Last_Name, First_Name, Phone, Email, Field1)
SELECT Last_name, First_Name, Phone, Email, Cust_ID 
from DB2..Customer DB2_Outer 
Where DB2_Outer.Cust_ID not in 
    (Select DB2_Inner.Cust_ID 
     from DB2..Customer DB2_Inner  
     Inner Join DB1..Customer DB1_Inner 
     on DB1_Inner.Last_Name=DB2_Inner.Last_Name 
         and DB1_Inner.First_Name=DB2_Inner.First_Name 
         and DB1_Inner.Email=DB2_Inner.Email) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 2020-08-20
    • 1970-01-01
    相关资源
    最近更新 更多