5

采访中被问到的一个问题是,

一张表有 100 条记录。其中 50 个是重复的。是否可以通过单个查询从表中删除重复记录以及选择并显示剩余的 50 条记录。

这可以在单个 SQL 查询中实现吗?

谢谢

国民账户体系

4

3 回答 3

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 的 2008 MERGE语法来实现这一点。

于 2010-01-28T08:16:08.027 回答
1

Lieven's Answer很好地解释了如何输出已删除的行。我想补充两点:

  1. 如果你想对输出做更多的事情而不是显示它,你可以指定OUTPUT INTO @Tbl(在哪里@Tbl是你在删除之前声明的 table-var);

  2. 使用MAXMIN或任何其他聚合只能处理每组一个重复的行。如果您可能有许多重复项,以下 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
)
于 2010-01-28T14:55:11.840 回答
0

听起来不太可能,至少在 ANSI SQL 中,因为 delete 只返回已删除行数的计数。

于 2010-01-28T07:29:20.943 回答