Tsql SQL删除具有重复值的行,同时保留一行

Tsql SQL删除具有重复值的行,同时保留一行,tsql,sql-server-2008-r2,Tsql,Sql Server 2008 R2,假设我有这张桌子 id | data | value ----------------- 1 | a | A 2 | a | A 3 | a | A 4 | a | B 5 | b | C 6 | c | A 7 | c | C 8 | c | C 我想删除每个数据中具有重复值的行,同时保留具有最小id的行,例如,结果将是 id | data | value ----------------- 1

假设我有这张桌子

id | data | value
-----------------
 1 |   a  |   A
 2 |   a  |   A
 3 |   a  |   A
 4 |   a  |   B
 5 |   b  |   C
 6 |   c  |   A
 7 |   c  |   C
 8 |   c  |   C
我想删除每个数据中具有重复值的行,同时保留具有最小id的行,例如,结果将是

id | data | value
-----------------
 1 |   a  |   A
 4 |   a  |   B
 5 |   b  |   C
 6 |   c  |   A
 7 |   c  |   C
我知道这样做的一个方法是建立一个工会,比如:

SELECT 1 [id], 'a' [data], 'A' [value] INTO #test UNION SELECT 2, 'a', 'A'
UNION SELECT 3, 'a', 'A' UNION SELECT 4, 'a', 'B'
UNION SELECT 5, 'b', 'C' UNION SELECT 6, 'c', 'A'
UNION SELECT 7, 'c', 'C' UNION SELECT 8, 'c', 'C'

SELECT * FROM #test WHERE id NOT IN (
    SELECT MIN(id) FROM #test
    GROUP BY [data], [value]
    HAVING COUNT(1) > 1
    UNION
    SELECT MIN(id) FROM #test
    GROUP BY [data], [value]
    HAVING COUNT(1) <= 1
)

但此解必须重复相同的组,两次考虑实际情况是一个大组,由20列

与复杂的答案相比,我更喜欢简单的答案,代码更少。有没有更简洁的编码方法

谢谢

有两种选择:

与CTE一起使用:

说明:

此查询将选择表的内容以及行号RN。然后删除RN>1的记录,这将是重复的记录

显示将使用此方法删除的记录

不在以下位置使用:

说明:

在给定的示例中,内部查询将返回ID1,6,4,5,7。外部查询将从id不在1,6,4,5,7中的表中删除记录

显示将使用此方法删除的记录


建议:使用第一种方法,因为它比后者快。此外,如果id字段也为相同的数据和值复制,则它只能保存一条记录。

我想为这个查询添加MYSQL解决方案

建议1:8.0之前的MySQL不支持WITH子句

建议2:抛出此错误。您不能在FROM子句中为update指定表TableName

因此,解决方案将是

DELETE FROM TableName WHERE id NOT IN
  (SELECT MIN(id) as id
   FROM (select * from TableName) as t1
   GROUP BY data,value) as t2;

请注意,如果您的数据完全重复,则这不起作用。唯一的区别是行号,它应该只用于选择组中编号最低的行。@EricBurel:如果所有字段都是重复的,那么在按列分区中添加id字段后,可以使用带有CTE的第一个解决方案。我在Postgres中使用物理行id找到了另一个解决方案,更广泛地说,一些特定于DBMS的特殊字段可能有助于区分在其他方面相同的行,但在第一个查询中手动添加id确实应该。
DELETE FROM TableName
WHERE id NOT IN
      (SELECT MIN(id) as id
       FROM TableName
       GROUP BY data,value)
DELETE FROM TableName WHERE id NOT IN
  (SELECT MIN(id) as id
   FROM (select * from TableName) as t1
   GROUP BY data,value) as t2;