【问题标题】:Removing duplicate SQL table rows [duplicate]删除重复的 SQL 表行 [重复]
【发布时间】:2023-04-10 11:09:01
【问题描述】:

我的 sql 表没有主键列。我可以找到重复的行,但我不知道如何删除到一个来休息;让我解释一下;

col1     col2    col3    col4
10       0       1000    1    
10       0       1000    1    --> should be deleted
10       0       1111    2    --> should be deleted
10       1       1000    1
10       2       1000    1
15       0       1000    1
15       0       1000    1    --> should be deleted
16       0       1000    1

我使用 col1 和 col2 来理解行是重复的。同时“10”“0”必须是唯一的,但表中可以包含多个“10”或多个“0”值。

谢谢。

【问题讨论】:

  • 我的第一个想法:添加一个自动增量 id 并使用该 ID 删除重复项。
  • 你使用什么 SQL ? (MySQL、PostgreSQL、MSSQL、Oracle 等)
  • @user2672165 其实我在问之前先在网上搜索。但是许多示例在列中有一个不同的值。我的复制品有时完全一样。我必须匹配第一列和第二列..
  • 好的,我可以调查这些主题并通知您。
  • 引用的问题都有一个“额外”的 id 列,这里似乎缺少,因此它们的解决方案不适用。

标签: sql sql-server


【解决方案1】:

这应该可行。它首先找出每个组合有多少重复项,然后将它们全部删除,但只有一个。

CREATE TABLE t_test (col1 int, col2 int, col3 int, col4 int)

INSERT t_test 
          SELECT 10, 0, 1000, 1 
UNION ALL SELECT 10, 0, 1000, 1 --> should be deleted
UNION ALL SELECT 10, 0, 1111, 2 --> should be deleted
UNION ALL SELECT 10, 1, 1000, 1
UNION ALL SELECT 10, 2, 1000, 1
UNION ALL SELECT 15, 0, 1000, 1
UNION ALL SELECT 15, 0, 1000, 1 --> should be deleted
UNION ALL SELECT 16, 0, 1000, 1

DECLARE @col1 int, @col2 int, @count int

DECLARE delete_loop CURSOR LOCAL STATIC
    FOR SELECT COUNT(*), col1, col2
          FROM t_test
         GROUP BY col1, col2
        HAVING COUNT(*) > 1
OPEN delete_loop
FETCH NEXT FROM delete_loop INTO @count, @col1, @col2
WHILE @@FETCH_STATUS = 0
    BEGIN
        DELETE TOP (@count - 1)
          FROM t_test
         WHERE col1 = @col1
           AND col2 = @col2

        FETCH NEXT FROM delete_loop INTO @count, @col1, @col2
    END
CLOSE delete_loop
DEALLOCATE delete_loop

SELECT * FROM t_test

编辑:调整为仅查看 col1 和 col2 的唯一性。

【讨论】:

  • 工作成功。感谢@deroby 的解决方案
  • 不客气。如果速度太慢,您可以先在 col1 和 col2 上添加索引,运行修复程序,然后他们再次删除索引。也就是说,如果还没有这样的索引的话。
【解决方案2】:

这是一种识别重复项并删除它们的简单方法。

为 col1 和 col2 的每个组合(分区依据)添加一个递增的 id,将其包装在 CTE 中,并删除不等于 1 的记录(第一次出现)。

DECLARE @Test TABLE (col1 int, col2 int, col3 int, col4 int)

INSERT @Test 
          SELECT 10, 0, 1000, 1 
UNION ALL SELECT 10, 0, 1000, 1 --> should be deleted
UNION ALL SELECT 10, 0, 1111, 2 --> should be deleted
UNION ALL SELECT 10, 1, 1000, 1
UNION ALL SELECT 10, 2, 1000, 1
UNION ALL SELECT 15, 0, 1000, 1
UNION ALL SELECT 15, 0, 1000, 1 --> should be deleted
UNION ALL SELECT 16, 0, 1000, 1

;WITH DUPES
AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY COL1,COL2 ORDER BY COL1,COL4) AS myID
FROM @Test
)

DELETE D
FROM DUPES D
WHERE myID <> 1

SELECT * 
FROM @Test

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-22
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 2019-12-04
    • 2010-11-22
    • 2017-11-16
    相关资源
    最近更新 更多