5

インタビューで尋ねられた質問の1つは、

1つのテーブルには100レコードがあります。それらの50は重複しています。1つのクエリで、重複するレコードをテーブルから削除し、残りの50レコードを選択して表示することは可能ですか。

これは単一のSQLクエリで可能ですか?

ありがとう

SNA

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行と同じである必要があります)、SQLServerの2008MERGE構文を使用してこれを実現できます。

于 2010-01-28T08:16:08.027 に答える
1

Lieven's Answerは、削除された行を出力する方法の良い説明です。2つ追加したいと思います。

  1. 出力を表示する以外に何かをしたい場合は、指定できますOUTPUT INTO @Tbl@Tbl削除される前に宣言したtable-varはどこにありますか)。

  2. MAX、、、MINまたはその他の集計を使用すると、グループごとに1つの重複行のみを処理できます。重複が多い可能性がある場合は、次のSQLServer2005以降のコードが役立ちます。

 

;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

削除は削除された行の数のカウントのみを返すため、少なくともANSISQLではありそうにありません。

于 2010-01-28T07:29:20.943 に答える