将重复记录与"合并"语法合并在一起

PJD*_*PJD 8 sql t-sql sql-server sql-server-2014

我正在使用SQL Server 2014.我目前正在尝试将数百万人员应用程序记录合并到一个人事记录中.

记录包含以下列:

ID, First_Name, Last_Name, DOB, Post_Code, Mobile, Email
Run Code Online (Sandbox Code Playgroud)

一个人可以多次输入他们的详细信息,但由于手指发胖或欺诈,他们有时可能会输入错误的细节.

在我的例子克里斯托弗在5倍充满了他的细节,First_Name,Last_Name,DOB总是正确的,Post_Code,MobileEmail含有多种内涵.

我想要做的是在这种情况下获取与此组相关联的min(id)84015283并将其放入新表中,这将是主键,然后您将看到与其关联的其他ID.

例子

NID       CID
------------------
84015283  84015283
84015283  84069198
84015283  84070263
84015283  84369603
84015283  85061159
Run Code Online (Sandbox Code Playgroud)

它变得有点复杂的地方是,2个不同的人可以拥有相同的First_Name,Last_Name并且DOB,至少有一个其他字段必须根据我的例子将" post_code,mobileemail" 匹配到组内的另一个记录.

虽然first_name,last_name,DoBID的84015283,84069198,84070263. 84015283之间的匹配,84069198是相同的,这样他们就匹配没有问题,84070263场的邮政编码比赛,在移动到前一个创纪录的84369603场比赛和85061159轮在以前的移动/电子邮件的比赛,但不是post_code.

如果将NID放在原始数据集中更容易,我可以使用它,而不是将它全部放在一个单独的表中.

经过一番谷歌搜索并尝试着解决这个问题,我相信使用"合并"可能是实现我目标的好方法,但我担心由于涉及的记录数量需要很长时间.

此外,任何例程都必须在随后的新记录中运行.

如果有人可以提供帮助,我已经列出了该示例的代码

DROP TABLE customer_dist

CREATE TABLE [dbo].customer_dist
(
    [id] [int] NOT NULL,
    [First_Name] [varchar](50) NULL,
    [Last_Name] [varchar](50) NULL,
    [DoB] [date] NULL,
    [post_code] [varchar](50) NULL,
    [mobile] [varchar](50) NULL,
    [Email] [varchar](100) NULL,
)

INSERT INTO customer_dist (id, First_Name, Last_Name, DoB, post_code, mobile, Email)
VALUES ('84015283', 'Christopher', 'Higg', '1956-01-13', 'CH2 3AZ', '07089559829', 'CH@hotmail.com'),
       ('84069198', 'Christopher', 'Higg', '1956-01-13', 'CH2 3AZ', '07089559829', 'CH@hotmail.com'),
       ('84070263', 'Christopher', 'Higg', '1956-01-13', 'CH2 3AZ', '07089559822', 'CHigg@AOL.com'),
       ('84369603', 'Christopher', 'Higg', '1956-01-13', 'CH2 3ZA', '07089559829', 'Higg@emailme.com'),
       ('85061159', 'CHRISTOPHER', 'Higg', '1956-01-13', 'CH2 3RA', '07089559829', 'CH@hotmail.com'),
       ('87065122', 'Matthew', 'Davis', '1978-05-10', 'CH5 1TS', '07077084692', 'Matt@gamil.com')

SELECT * FROM customer_dist
Run Code Online (Sandbox Code Playgroud)

以下是预期的结果,对不起我应该更清楚地说明我想要的结果.

输出表结果

    NID         id          First_Name  Last_Name   DoB         post_code   mobile          Email
    84015283    84015283    Christopher Higg            1/13/1956   CH2 3AZ         7089559829  CH@hotmail.com
    84015283    84069198    Christopher Higg            1/13/1956   CH2 3AZ         7089559829  CH@hotmail.com
    84015283    84070263    Christopher Higg            1/13/1956   CH2 3AZ         7089559822  CHigg@AOL.com
    84015283    84369603    Christopher Higg            1/13/1956   CH2 3ZA         7089559829  Higg@emailme.com
    84015283    85061159    CHRISTOPHER Higg            1/13/1956   CH2 3RA         7089559829  CH@hotmail.com
    78065122    87065122    Matthew Davis               05/10/1978  CH5 1TS
Run Code Online (Sandbox Code Playgroud)

7077084692 Matt@gamil.com

OR                          

NID         id
84015283    84015283
84015283    84069198
84015283    84070263
84015283    84369603
84015283    85061159
87065122    87065122
Run Code Online (Sandbox Code Playgroud)

抱歉,反应缓慢.

我已经更新了我的所需输出,我被要求包含一个与其他记录不匹配的额外记录,但未在我的所需输出中包含此记录.

HABO的响应最接近于在进一步测试其他样本数据时所需响应,创建了重复项并且逻辑崩溃了.其他样本数据如下: -

declare @customer_dist as Table (
    [id] [int] NOT NULL,
    [First_Name] [varchar](50) NULL,
    [Last_Name] [varchar](50) NULL,
    [DoB] [date] NULL,
    [post_code] [varchar](50) NULL,
    [mobile] [varchar](50) NULL,
    [Email] [varchar](100) NULL );


INSERT INTO @customer_dist (id, First_Name, Last_Name, DoB, post_code, mobile, Email)
VALUES ('32006455', 'Mary', 'Wilson',   '1983-09-20',   'BT62JA',   '07706212920',  'nastie220@yahoo.com'),
       ('35963960', 'Mary', 'Wilson',   '1983-09-20',   'BT62JA',   '07484863324',  'nastie@hotmail.com'),
       ('38627975', 'Mary', 'Wilson',   '1983-09-20',   'BT62JA',   '07484863478',  'nastie2001@yahoo.com'),
       ('46653041', 'Mary', 'WILSON',   '1983-09-20',   'BT62JA',   '07483888179',  'nastie2010@yahoo.com'),
       ('48023677', 'Mary', 'Wilson',   '1983-09-20',   'BT62JA',   '07483888179',  'nastie@hotmail.com'),
       ('49560434', 'Mary', 'Wilson',   '1983-09-20',   'BT62JA',   '07849727199',  'nastie@hotmail.com'),
       ('49861032', 'Mary', 'WILSON',   '1983-09-20',   'BT62JA',   '07849727199',  'nastie2001@yahoo.com'),
       ('53130969', 'Mary', 'Wilson',   '1983-09-20',   'BT62JA',   '07849727199',  'Nastie@hotmail.cm'),
       ('33843283', 'Mary', 'Wilson',   '1983-09-20',   'BT148HU',  '07484863478',  'nastie2010@yahoo.co.uk'),
       ('38627975', 'Mary', 'Wilson',   '1983-09-20',   'BT62JA',   '07484863478',  'nastie2001@yahoo.com')

SELECT * FROM @customer_dist;
Run Code Online (Sandbox Code Playgroud)

The*_*ler 0

这不是答案,而是评论太长,无法放入评论部分。

由于“平等”条件很复杂,我想我会分阶段进行:

  1. 创建类似客户的“桶”。存储桶标识具有相同 id、first_name、last_name 和 dob 的所有客户。在新的“键”列上添加索引以加快分组速度。一个存储桶可能包含一个或多个真实客户。

    select
        cast(id as varchar(10)) +
        lower(first_name) + 
        lower(last_name) + 
        convert(varchar, dob, 23) as k,
        id, post_code, mobile, email
        into bucket
      from customer_dist;
    
    create index ix1 on bucket(k);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 对每个桶进行处理,并将每个桶上的客户分开。很可能只有一个,但也可以有多个。

在这里,您需要运行一些迭代算法来比较行,将它们标记为相等的组或不同的组,并最终将组合并为单个组。所有这些都是可能的,但恐怕我不知道如何简单地在 SQL 中做到这一点。

您需要在这里进行一些编码。