在不使用临时表的情况下从表中删除重复项

时间:2010-05-09 05:49:20

标签: sql sql-server tsql

我有一个表(TableA),内容如下:

Col1
-----
 A
 B
 B
 B
 C 
 C
 D

我想仅使用 Microsoft SQL Server 中的临时表删除重复值而不使用。谁能帮我? 决赛桌应如下所示:

Col1
-----
 A
 B
 C 
 D

谢谢:)

5 个答案:

答案 0 :(得分:4)

WITH TableWithKey AS (
SELECT ROW_NUMBER() OVER (ORDER BY Col1) As id, Col1 As val
FROM TableA
)
DELETE FROM TableWithKey WHERE id NOT IN
(
SELECT MIN(id) FROM TableWithKey
GROUP BY val
)

答案 1 :(得分:2)

你可以使用row_number()函数(http://msdn.microsoft.com/en-us/library/ms186734.aspx)按你正在寻找dupes的列进行分区,并删除行号不是1的地方吗?

答案 2 :(得分:0)

我完全同意拥有唯一标识符可以为您节省大量时间。

但是如果你不能使用一个(或者如果这纯粹是假设的话),这里有另一种选择:确定要删除的行数(每个不同值的计数-1),然后循环并删除顶部X每个不同的价值。

请注意,我不对每次使用动态SQL时被杀死的小猫数量负责。

declare @name varchar(50)
declare @sql varchar(max)
declare @numberToDelete varchar(10) 
declare List cursor for
    select name, COUNT(name)-1 from #names group by name
OPEN List
FETCH NEXT FROM List 
INTO @name,@numberToDelete
WHILE @@FETCH_STATUS = 0
BEGIN
  IF @numberToDelete > 0
  BEGIN
    set @sql = 'delete top(' + @numberToDelete + ') from #names where name=''' + @name + ''''
    print @sql
    exec(@sql)
  END
  FETCH NEXT FROM List INTO @name,@numberToDelete
END
CLOSE List
DEALLOCATE List

另一种方法是创建一个带有生成身份的视图。通过这种方式,您可以将值映射到唯一标识符(允许常规删除),而无需对表进行永久添加。

答案 3 :(得分:0)

选择分组数据到临时表,然后截断原始数据,然后将其移回原始数据。

第二个解决方案,我不确定它是否可行,但您可以直接从SQL Management Studio尝试打开表,并在选定的行上使用CTRL + DEL来删除它们。这将非常缓慢,因为您需要手动删除每一行。

答案 4 :(得分:0)

您可以使用光标和DELETE .. WHERE CURRENT OF删除重复的行。

CREATE TABLE Client ([name] varchar(100))
INSERT Client VALUES('Bob')
INSERT Client VALUES('Alice')
INSERT Client VALUES('Bob')
GO
DECLARE @history TABLE (name varchar(100) not null)
DECLARE @cursor CURSOR, @name varchar(100)
SET @cursor = CURSOR FOR SELECT name FROM Client
OPEN @cursor
FETCH NEXT FROM @cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
    IF @name IN (SELECT name FROM @history)
        DELETE Client WHERE CURRENT OF @cursor
    ELSE
        INSERT @history VALUES (@name)

    FETCH NEXT FROM @cursor INTO @name
END