将重复查找器查询转换为删除所有但最新记录

时间:2014-10-10 12:05:58

标签: mysql

我有一个重复的查询程序查询...

SELECT
    Author, Name, TrackNum, title_id, COUNT(*)
FROM
    db.table
GROUP BY
    Author, Name, TrackNum, title_id
HAVING 
    COUNT(*) > 1

它返回那些重复的记录,以及有多少记录。

我想对此进行扩展,以便删除除每个副本的最新版本之外的所有副本。我想我们可以使用表中提供的iddatetime字段来标识要保留的记录。或者还有另一种方式吗?

编辑:我已经到了一半...

SELECT
    *
FROM
    db.table
GROUP BY
    Author, Name, TrackNum, title_id
HAVING 
    COUNT(*) > 1
ORDER BY
    Name, TrackNum

以上似乎显示了每个副本的一个副本。当我在工作台中删除它们时,我只剩下剩余的最新唯一记录。我想进一步自动化这一步。此外,这不会占两个以上相同的记录。

1 个答案:

答案 0 :(得分:1)

建议的解决方案

#
# Step 01) Create Temp Key Tables
#
CREATE TABLE KeysToKeep
(
    id INT NOT NULL,
    PRIMARY KEY (id)
);
CREATE TABLE KeysToDrop LIKE KeysToKeep;
#
# Step 02) Collect All id values you want to Keep
#
INSERT INTO KeysToKeep
    SELECT id FROM
    (SELECT MAX(id) id,Author, Name, TrackNum, title_id
    FROM db.table GROUP BY Author, Name, TrackNum, title_id) A
;
#
# Step 03) Collect All id values you want to Drop
#
INSERT INTO KeysToDrop
SELECT A.id FROM db.table A LEFT JOIN KeysToKeep USING (id) WHERE B.id IS NULL;
#
# Step 04) Do the Mass Delete 
#
DELETE A.* FROM db.table A INNER JOIN KeysToDrop B USING (id);
#
# Step 05) Remove Temp Key Tables
#
DROP TABLE KeysToKeep;
DROP TABLE KeysToDrop;

建议的解决方案(更短的版本)

#
# Step 01) Create Temp Key Table
#
CREATE TABLE KeysToKeep
(
    id INT NOT NULL,
    PRIMARY KEY (id)
);
#
# Step 02) Collect All id values you want to Keep
#
INSERT INTO KeysToKeep
    SELECT id FROM
    (SELECT MAX(id) id,Author, Name, TrackNum, title_id
    FROM db.table GROUP BY Author, Name, TrackNum, title_id) A
;
#
# Step 03) Do the Mass Delete 
#
DELETE A.* FROM db.table A LEFT JOIN KeysToKeep B USING (id) WHERE B.id IS NULL;
#
# Step 04) Remove Temp Key Table
#
DROP TABLE KeysToKeep;

提议的解决方案(偏执狂版本)

#
# Step 01) Create Temp Key Table
#
CREATE TABLE KeysToKeep
(
    id INT NOT NULL,
    PRIMARY KEY (id)
);
#
# Step 02) Collect All id values you want to Keep
#
INSERT INTO KeysToKeep
    SELECT id FROM
    (SELECT MAX(id) id,Author, Name, TrackNum, title_id
    FROM db.table GROUP BY Author, Name, TrackNum, title_id) A
;
#
# Step 03) Copy the Tables to Keep to Another Temp Table
#
CREATE TABLE db.table_new LIKE db.table;
INSERT INTO db.table_new
SELECT A.* FROM db.table A INNER JOIN KeysToKeep B USING (id);
#
# Step 04) Swap New and Old Tables
#
ALTER TABLE db.table RENAME db.table_old;
ALTER TABLE db.table_new RENAME db.table;
#
# Step 05) Remove Temp Key Table
#
DROP TABLE KeysToKeep;
#
# Step 06) Drop the Old Table If the Content of db.table is Correct
#
DROP TABLE db.table_old;

EPILOGUE

在前两种情况下,请检查KeysToKeep和/或KeysToDrop以确保它们是保持或删除的关键。在最后一种情况下,如果您确定,请删除表db.table_old。如果您不确定,可以像这样回滚:

ALTER TABLE db.table RENAME db.table_new;
ALTER TABLE db.table_old RENAME db.table;

给它一个尝试!