51

主キーのないデータベース テーブルを一掃しています (わかっています、わかっています、彼らは何を考えていたのでしょうか?)。キーになる列に重複があるため、主キーを追加できません。重複値は、すべての点で同一である 2 つの行のうちの 1 つから取得されます。主キー (または少なくとも UQ NN 列) のないテーブルでタスクを実行することを拒否するため、GUI (この場合は MySQL Workbench ですが、データベースに依存しないアプローチを探しています) を介して行を削除できません。キーになる列に重複があるため、主キーを追加できません。重複値は1つから来ます...

双子の一方を削除するにはどうすればよいですか?

4

18 に答える 18

24

DELETEMySQL にはという独自の拡張子があることに注意しDELETE ... LIMITくださいLIMIT

DELETE に対する MySQL 固有の LIMIT row_count オプションは、制御がクライアントに返される前に削除される行の最大数をサーバーに伝えます。これを使用して、特定の DELETE ステートメントに時間がかかりすぎないようにすることができます。影響を受ける行の数が LIMIT 値より少なくなるまで、単純に DELETE ステートメントを繰り返すことができます。

したがって、DELETE FROM some_table WHERE x="y" AND foo="bar" LIMIT 1;「1 つを除いてすべてを削除する」という簡単な方法はないことに注意してください。行の重複がまだあるかどうかを確認し続けてください。

于 2013-05-08T11:54:09.117 に答える
19

delete top(1) は、Microsoft SQL Server (T-SQL) で動作します。

于 2015-12-01T08:35:41.423 に答える
11

ROW_NUMBER()これは、以下のように CTE と関数を使用して実現できます。

/* Sample Data */
    CREATE TABLE #dupes (ID INT, DWCreated DATETIME2(3))

    INSERT INTO #dupes (ID, DWCreated) SELECT 1, '2015-08-03 01:02:03.456'
    INSERT INTO #dupes (ID, DWCreated) SELECT 2, '2014-08-03 01:02:03.456'
    INSERT INTO #dupes (ID, DWCreated) SELECT 1, '2013-08-03 01:02:03.456'

/* Check sample data - returns three rows, with two rows for ID#1 */
    SELECT * FROM #dupes 

/* CTE to give each row that shares an ID a unique number */
    ;WITH toDelete AS
      (
        SELECT ID, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DWCreated) AS RN
        FROM #dupes 
      )

  /* Delete any row that is not the first instance of an ID */
    DELETE FROM toDelete WHERE RN > 1

/* Check the results: ID is now unique */
    SELECT * FROM #dupes

/* Clean up */
    DROP TABLE #dupes

ORDER BY する列があると便利ですが、どの行を削除するかを優先する場合を除き、必須ではありません。これにより、一度に 1 つの行を強制的に削除するのではなく、重複レコードのすべてのインスタンスも処理されます。

于 2016-02-05T16:41:20.203 に答える
3

私の場合、問題の行の値の文字列を GUI に表示させることができました (別の方法として、これを手動で行うこともできました)。私が借金を抱えている同僚の提案で、私はこれを使用して INSERT ステートメントを作成しました。

INSERT
'ID1219243408800307444663', '2004-01-20 10:20:55', 'INFORMATION', 'admin' (...)
INTO some_table;

挿入ステートメントをテストしたので、トリプレットができました。最後に、単純な DELETE を実行してそれらをすべて削除しました...

DELETE FROM some_table WHERE logid = 'ID1219243408800307444663';

もう一度 INSERT を実行すると、行が 1 つ残り、主キーの明るい可能性が広がります。

于 2013-05-08T10:29:20.070 に答える
0
delete top(1) tableNAme 
where --your conditions for filtering identical rows
于 2022-03-05T12:58:14.457 に答える
0

PostgreSQLには、 という暗黙の列がありますctidウィキを参照してください。そのため、以下を自由に使用できます。

WITH cte1 as(
    SELECT unique_column, max( ctid ) as max_ctid
    FROM table_1
    GROUP BY unique_column
    HAVING count(*) > 1
), cte2 as(
    SELECT t.ctid as target_ctid
    FROM table_1 t
    JOIN cte1 USING( unique_column )
    WHERE t.ctid != max_ctid
)
DELETE FROM table_1
WHERE ctid IN( SELECT target_ctid FROM cte2 )

同時更新の可能性がある場合にこれを使用することがどれほど安全かはわかりません。LOCK TABLE table_1 IN ACCESS EXCLUSIVE MODE;そのため、実際にクリーンアップを行う前にを作成するのが賢明であることに気付くかもしれません。

于 2017-04-11T11:06:03.483 に答える
0

Employee テーブルから 1 つの一意のレコードのみを保持して重複レコードを削除するとします - Employee(id,name,age)

delete from Employee
where id not in (select MAX(id)
                  from Employee
                  group by (id,name,age)
                );
于 2021-06-13T01:37:57.643 に答える