Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL删除空白(重复)_Sql_Sql Server 2008 - Fatal编程技术网

SQL删除空白(重复)

SQL删除空白(重复),sql,sql-server-2008,Sql,Sql Server 2008,我有一个电话数据库,有大约30万条记录 我想做的是删除空白,如下所示:- update SMSTelephone set Telephone = replace(Telephone, ' ', '') 问题是,当我执行此操作时,会出现以下错误:- Msg 2627, Level 14, State 1, Line 1 Violation of PRIMARY KEY constraint 'PK_SMSTelephone'. Cannot insert duplicate key in

我有一个电话数据库,有大约30万条记录

我想做的是删除空白,如下所示:-

update SMSTelephone set
Telephone = replace(Telephone, ' ', '')
问题是,当我执行此操作时,会出现以下错误:-

Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'PK_SMSTelephone'. Cannot insert duplicate key in     object 'dbo.SMSTelephone'.
The statement has been terminated.
我猜这是因为我可能有这样一张唱片:

  • 07777777
  • 07777
  • 因此,删除空白将失败,因为这两个记录将被复制

    在不更新任何可能导致重复的记录的情况下,是否仍可以执行此命令

    任何帮助都将不胜感激

    试试这个:

    update ST set
      Telephone = replace(st.Telephone, ' ', '')
    from SMSTelephone st
    cross apply (select count(*) as cnt
                 from SMSTelephone sti
                 where replace(st.Telephone, ' ', '')=replace(sti.Telephone, ' ', '')) i
    where i.cnt=1
    
    要更新其中一个,请执行以下操作:

    WITH CTE (Telephone,DuplicateCount)
    AS
    (
      SELECT Telephone,
      ROW_NUMBER() OVER(PARTITION BY replace(Telephone, ' ', '') ORDER BY len(Telephone)) AS DuplicateCount
      FROM SMSTelephone
    )
    update CTE
    set Telephone = replace(Telephone, ' ', '')
    WHERE DuplicateCount = 1
    
    要删除除一个以外的所有内容,请执行以下操作:

    WITH CTE (Telephone,DuplicateCount)
    AS
    (
      SELECT Telephone,
      ROW_NUMBER() OVER(PARTITION BY replace(Telephone, ' ', '') ORDER BY len(Telephone)) AS DuplicateCount
      FROM SMSTelephone
    )
    delete from CTE
    WHERE DuplicateCount > 1
    
    提琴用于更新(类似于删除)


    我假设您这样做是因为数据是手动输入的,或者是由未对输入进行消毒的应用程序输入的,然后检查现有记录


    一个相当复杂的解决方案是添加一个WHERE子句,该子句搜索与已清理字符串匹配的任何内容,然后将其排除。

    要使该列成为有效的PK,输入数据实际上应该已清理(DBA讲座结束)

    对于单列表,通常需要为干净数据创建镜像表:

    CREATE TABLE SMSTelephoneBak
    ( Telephone VARCHAR(20)
    );
    
    将干净的数据插入其中:

    INSERT into SMSTelephoneBak
    SELECT DISTINCT REPLACE(telephone,' ','') FROM dbo.SMSTelephone;
    
    清除源表:

    TRUNCATE TABLE dbo.SMSTelephone;
    
    插入已清除的数据:

    INSERT INTO dbo.SMSTelephone 
            ( Telephone )
    SELECT Telephone FROM dbo.SMSTelephoneBak;
    
    最后,删除临时表:

    DROP TABLE dbo.SMSTelephonebak;
    

    我猜
    电话
    栏是你的主键吧?如果是这样,那么我假设你无论如何都不想要任何副本,那么当它们出现时会发生什么呢?您是否保留了一行,并以某种方式合并了其他行?您可能还需要考虑向字段添加<代码>检查<代码>约束,以确保它只包含数字。我刚刚收到
    (0行受影响)
    效果不错!但是,如果您有两个这样的数字:
    07777777
    077777
    这将失败,因为它将尝试更改这两个数字,我将再次获得重复的字段。我刚刚尝试使用这两个精确的数字,我得到了
    (受影响的0行)
    。。它也不会更新。只有当只有一个版本的电话可用时,它才会更新。这是你问的。为什么不删除重复项,然后进行更简单的更新。如果两个数字都是:
    077777
    077777
    ,是否可以修剪其中一个?或者甚至删除重复的一个与空间,因为这一个将不需要。这似乎是最好的方法,只要重复的是真正的重复。例如,如果您查看两条记录,其中一条电话号码为777 7777,另一条电话号码为777 777,那么这些记录中的其余列是否都匹配,或者在某些方面是否有所不同。如果其余立柱不同,则需要进行更多工作。如果有其他列并且它们匹配,那么您需要使用一些聚合函数(如avg或max)将其添加到select distinct语句中。是的,我概述的解决方案是问题中描述的简单(单列)场景。聚合来自其他列的数据是一个完全不同的主题…很高兴我们在这个问题的数据清理方面达成一致。公平点。。根据我的经验,这类问题不适合于干净的解决方案。想到中间表的使用。