【问题标题】:Removing duplicates from a single column从单个列中删除重复项
【发布时间】:2012-08-08 06:45:55
【问题描述】:

我有一张这样的桌子:

表格

id
=====
1
1
2
2
6
6
7
5
5
9

除了创建新表之外,我还需要删除重复项。 一种方法是:

create table_new (select distinct id from table )

是否有删除重复项的删除命令?

【问题讨论】:

标签: mysql sql


【解决方案1】:

恕我直言,在普通情况下(Ansi SQL)你不能这样做,因为没有唯一的关键字段你不能区分一行和另一行,所以你不能删除它。

但是在 MySQL 中你可以运行这个 UGLY 查询。它使用@S sting 来累积 ID,所以不要在大桌子上使用它:

set @S:=',';
delete from t 
where if(LOCATE(CONCAT(',',ID,','),@S)>0,'del',@S:=CONCAT(@S,ID,','))='del'

【讨论】:

    【解决方案2】:

    你可以使用 cte:

    ;WITH cte
         AS (SELECT ROW_NUMBER() OVER (PARTITION BY ID 
                                           ORDER BY ( SELECT 0)) RN
             FROM   #MyTable)
    DELETE FROM cte
    WHERE  RN > 1
    

    这将避免为您的不同记录创建临时表或保留表。如果您有其他列可能包含重复值,则可以在 PARTITION BY 表达式中的 ID 之后添加它们。

    虽然我会担心为什么您有重复的 ID 值。

    • 如果这是一个行 ID,那么我建议使用 IDENTITY 和 自动增加 ID。
    • 如果它是一个项目或参考 ID,那么我会尽量避免添加重复项(这可能是完全错误的,具体取决于您的结构)

    【讨论】:

      【解决方案3】:

      【讨论】:

      • 谢谢,但我的表格中只有一列,所以你的例子不适合我的情况
      【解决方案4】:

      删除所有重复项的单个查询(在 Oracle 中测试)

      从 my_table 中删除 rowid 不在 (select min(rowid) from temp_table group by id);

      解释:

      默认情况下,Oracle 给每一行一个 rowid(我确信其他数据库有相同或相似的东西)。

      让我们先看一下内部查询。 Group by 子句根据一些标准对行进行分组,在我们的例子中是 Id。我们也可以基于多个列进行分组(按 col1、col2 分组)。当我们说 min(rowid) 时,我们只是确保它返回一个 rowid,以防多行具有重复的列。

      外部删除查询很简单,它只是从表中删除我们内部查询未返回的所有其他内容(重复项)

      【讨论】:

      【解决方案5】:

      删除重复行的最佳方法是提供一个唯一标识表中每条记录的主键列。

      【讨论】:

        【解决方案6】:

        我不确定是否有任何直接实现,但这里有一个您可能感兴趣的函数实现。

        function RemoveDuplicates($TableName, $UniqueFieldName, $IDFieldName, $FirstFoundIDValue)
        {
            $Query =    "DELETE  FROM ".$TableName." ".
                        "WHERE    ".$IDFieldName." IN ".
                        "( SELECT a.".$IDFieldName." ".
                            "FROM ".$TableName." a, ".$TableName." b ".
                            "WHERE (a.".$UniqueFieldName." = b.".$UniqueFieldName.") ".
                            "AND (a.".$IDFieldName." > ".$FirstFoundIDValue.") ".
                            "GROUP BY a.".$IDFieldName." ".
                            "HAVING COUNT(a.".$UniqueFieldName.") > 1 ".
                        ")";
            db_query($Query);
        
        // Example Use:            
        // delete  from tblps_CommEquip 
        // where PSID in    
        // ( select a.PSID from tblps_CommEquip a, tblps_CommEquip b     
        //      where    (a.CommEquipType = b.CommEquipType) 
        //      AND (a.PSID > 80)    
        //      group by a.PSID 
        //      having count(a.CommEquipType) > 1
        // )
        } 
        

        【讨论】:

          【解决方案7】:

          第一次上谷歌:

          http://support.microsoft.com/kb/139444/en-us?fr=1

          文章描述了使用临时表来保存唯一记录,清除原始表并将唯一记录添加回其中,您可能可以通过编写一些存储过程来做到这一点,但我想您只需要这样做一次?然后我会按照描述的方法去。此外,为了防止将来出现问题,请对该字段使用唯一键或主键约束,这样就不可能有 2 条记录具有相同的值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-09-30
            • 2018-05-16
            • 2020-03-16
            • 2013-10-07
            • 2014-09-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多