完全相同的行
如果您想避免完全相同的行,正如我最初理解您的问题那样,那么您可以选择一个单独的表中的唯一行并从中重新创建表数据。
CREATE TEMPORARY TABLE tmp SELECT DISTINCT * FROM business_users;
DELETE FROM business_users;
INSERT INTO business_users SELECT * FROM tmp;
DROP TABLE tmp;
但是,如果有任何外键约束引用此表,请小心,因为临时删除行可能会导致其他地方的级联删除。
引入唯一约束
如果您只关心 user_id 和 business_id 对,您可能希望避免在将来引入重复项。您可以将现有数据移动到临时表中,添加约束,然后将表数据移回,忽略重复项。
CREATE TEMPORARY TABLE tmp SELECT * FROM business_users;
DELETE FROM business_users;
ALTER TABLE business_users ADD UNIQUE (user_id, business_id);
INSERT IGNORE INTO business_users SELECT * FROM tmp;
DROP TABLE tmp;
以上答案基于this answer。关于外键的警告与上一节一样适用。
一次性移除
如果您只想执行单个查询,而不以任何方式修改表结构,并且您有一个主键id 标识每一行,那么您可以尝试以下操作:
DELETE FROM business_users WHERE id NOT IN
(SELECT MIN(id) FROM business_users GROUP BY user_id, business_id);
this answer 之前提出了类似的想法。
如果上述请求失败,由于不允许在同一步骤中读取和删除表,您可以再次使用临时表:
CREATE TEMPORARY TABLE tmp
SELECT MIN(id) id FROM business_users GROUP BY user_id, business_id;
DELETE FROM business_users WHERE id NOT IN (SELECT id FROM tmp);
DROP TABLE tmp;
如果您愿意,您仍然可以在以这种方式清理数据后引入唯一性约束。为此,请执行上一节中的 ALTER TABLE 行。