在采访中提出的一个问题是,
一张表有100条记录。其中50个 是重复的。是否有可能单一 查询以删除重复记录 从表中以及选择和 显示剩余的50条记录。
这可以在单个SQL查询中使用吗?
谢谢
SNA
答案 0 :(得分:6)
使用SQL Server,您可以使用类似这样的内容
DECLARE @Table TABLE (ID INTEGER, PossibleDuplicate INTEGER)
INSERT INTO @Table VALUES (1, 100)
INSERT INTO @Table VALUES (2, 100)
INSERT INTO @Table VALUES (3, 200)
INSERT INTO @Table VALUES (4, 200)
DELETE FROM @Table
OUTPUT Deleted.*
FROM @Table t
INNER JOIN (
SELECT ID = MAX(ID)
FROM @Table
GROUP BY PossibleDuplicate
HAVING COUNT(*) > 1
) d ON d.ID = t.ID
OUTPUT语句显示被删除的记录。
更新:
上面的查询将删除重复项,并为您提供已删除的行,而不是剩余的行。如果这对您很重要(总而言之,其余50行应与50个已删除的行相同),您可以使用SQL Server's 2008 MERGE语法来实现此目的。
答案 1 :(得分:1)
Lieven's Answer是如何输出已删除行的一个很好的解释。我想补充两件事:
如果您希望使用除显示之外的输出执行更多操作,可以指定OUTPUT INTO @Tbl
(其中@Tbl
是您在删除之前声明的表格变量);
使用MAX
,MIN
或任何其他聚合只能处理每个组的一个重复行。如果您可能有许多重复项,则以下SQL Server 2005+代码将有助于实现此目的:
;WITH Duplicates AS
(
SELECT
ID,
ROW_NUMBER() OVER (PARTITION BY DupeColumn ORDER BY ID) AS RowNum
)
DELETE FROM MyTable
OUTPUT deleted.*
WHERE ID IN
(
SELECT ID
FROM Duplicates
WHERE RowNum > 1
)
答案 2 :(得分:0)
不太可能,至少在ANSI SQL中,因为删除只返回已删除行数的计数。