【问题标题】:Merge records in SQL SERVER在 SQL SERVER 中合并记录
【发布时间】:2015-02-05 09:23:12
【问题描述】:

我需要规范化包含anagraphic 数据的表。 这是一个包含一些行的示例表:

Id 姓氏 名字 地址 电子邮件 电话 手机 年龄 1 罗西马里奥 Via Milano NULL 123456 NULL 41 2 罗西马里奥 NULL rm@test.it 123456 NULL NULL 3 Rossi Mario Via Milano NULL NULL 254521 NULL

我想合并记录中的值,以便拥有一个包含所有值的唯一记录。 像这样:

Id 姓氏 名字 地址 电子邮件 电话 手机 年龄 1 罗西马里奥通过米兰 rm@test.it 123456 254521 41

我尝试使用 MERGE 语句,但我认为这不是正确的解决方案。

感谢任何帮助。

【问题讨论】:

  • 您如何决定应该合并哪些记录?
  • 你应该澄清所有不同的场景。比如如果有两个地址为同一个人或两个手机等。顺便说一句,Deepshikha 查询很好。
  • 嗨。谢谢您的回答。如果两条记录有两个不同的地址,我不想合并这条记录。

标签: sql sql-server merge


【解决方案1】:

如果您考虑将FirstNameLastName 作为关键标识符,那么您可以写成:

SELECT MIN(Id),     
       T1.LastName ,
       T1.FirsName,       
        SUBSTRING ((SELECT DISTINCT  CASE WHEN T2.Address IS NULL
        THEN '' ELSE ','+ T2.Address END  
        FROM @Test T2 
        WHERE T1.LastName = T2.LastName AND T1.FirsName = T2.FirsName
        FOR XML PATH('')),2,8000) AS [Address],
        SUBSTRING ((SELECT DISTINCT  CASE WHEN T3.Email  IS NULL 
        THEN '' ELSE ','+ T3.Email END
        FROM @Test T3 
        WHERE T1.LastName = T3.LastName AND T1.FirsName = T3.FirsName
    FOR XML PATH('')),2,8000)AS Email
FROM @Test T1
GROUP BY T1.LastName ,T1.FirsName

【讨论】:

  • 太棒了!我不知道 FOR XML PATH 。非常感谢!
【解决方案2】:

我认为这可能会对您有所帮助:-

UPDATE TAB_NAME
SET ID = MIN(ID), LastName = MAX(LastName), FirsName = MAX(FirsName)
    Address = MAX(Address), Email = MAX(Email), Tel = MAX(Tel), 
    Mobile = MAX(Mobile), Age = MAX(Age)
WHERE COND.;

【讨论】:

    【解决方案3】:

    您正在查看一个两步操作。要么将合并的数据插入新表,然后删除原始表,要么用合并的数据更新一行并删除所有额外的行。乍一看,前一种方法似乎最简单。

    insert into NewTable( ID, LastName, FirstName, Address, Email, ...
        select  Min( ID ), LastName, FirstName, Min( Address ), Min( Email ), ...
    from   OldTable
    group by LastName, FirstName;
    
    drop   OldTable;
    
    exec sp_rename 'NewTable', 'OldTable'; -- Optional
    

    但您可能没有删除和重命名表的权限。另外,您必须确保复制任何触发器、索引、约束等。

    后一种方法在 DML 方面有点棘手,但更安全。

    with
    New as(
        select  Min( ID ) MinID, LastName, FirstName,
                Min( Address ) MinAddr, Min( Email ) MinEmail, 
                Min( Tel ) MinTel, Min( Mobile ) MinMobil, Min( Age ) MinAge
        from    OldTable
        group by LastName, FirstName
    )
    update  Old
        set Old.Address = New.MinAddr,
            Old.Email   = New.MinEmail,
            Old.Tel     = New.MinTel,
            Old.Mobile  = New.MinMobil,
            Old.Age     = New.MinAge
    from    OldTable    Old
    join    New
        on  New.MinID = Old.ID;
    
    select * from OldTable;
    
    with
    MinIDs as(
        select  Min( ID ) MinID, LastName, FirstName
        from    OldTable
        group by LastName, FirstName
    )
    delete from Old
    from    OldTable Old
    join    MinIDs    MI
        on  MI.MinID < Old.ID;
    

    如果您将MinMax 与非关键字段一起使用,这并不重要。这是后一种方法的 Fiddle

    【讨论】:

      猜你喜欢
      • 2012-04-10
      • 2011-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 2018-06-11
      相关资源
      最近更新 更多