我的数据库中有三个字段:名字,姓氏和电子邮件。电子邮件是我的主键。我的数据库中没有其他字段。
我需要找到一个mysql查询,可以从数据库中删除重复的主键和它们的值,在数据库中只留下一个唯一的电子邮件。
我使用以下命令显示所有重复的主键。它工作了,但我需要删除所有其他重复的条目,只保留一个。我正在使用php编程。
SELECT *
FROM table_name
WHERE primarykey IN (
SELECT primarykey
FROM table_name
GROUP BY primarykey
HAVING count(primarykey) > 1
)
ORDER BY primarykey
用您想要保留的表填充临时表,在其他列上使用GROUP BY、HAVING和MAX。然后运行删除太多内容的查询,然后将复制的内容放回去。然后让它成为实际的PK,这样就不会再发生了
您不能只使用一个查询,因为您将需要使用limit
,并且需要对其进行硬设置。(例如,你不能说limit someColumn
。)
$query = "select primarykey, count(primarykey) as count from table_name group by primarykey having count(primarykey) > 1"
$result = $mysqli->query($query);
while ($row = $result->fetch_assoc()) {
$query = "delete from table_name where primarykey = ? limit " . $row['count'];
$stmt = $mysqli->prepare($query);
$stmt->bind_param('s', $row['primarykey']);
$stmt->execute();
}
Email是不是你的主键。主键在不允许重复的地方有约束。顺便说一下,您的问题只是一个示例,说明为什么您希望在所有表上都有一个自动递增的数字主键。似乎太晚了。
解决这个问题的一个方法是使用临时表。这个想法是复制数据,然后重新插入:
create temporary table tmp_emails as
select email, firstname, lastname
from emails
group by email;
truncate table emails;
insert into emails(email, firstname, lastname)
select email, firstname, lastname
from tmp_emails;
你能试试吗?
DELETE t1 FROM test t1, test t2
WHERE t1.email = t2.email
AND t1.fn > t2.fn
AND t1.ln > t2.ln;
以下是测试:
CREATE TABLE test
(
email varchar(100),
fn varchar(100),
ln varchar(100)
);
INSERT INTO test VALUES('a@b', 'f1', 'l1');
INSERT INTO test VALUES('a@b', 'f2', 'l2');
INSERT INTO test VALUES('c@d', 'f2', 'l2');
mysql> SELECT * FROM test;
+-------+------+------+
| email | fn | ln |
+-------+------+------+
| a@b | f1 | l1 |
| a@b | f2 | l2 |
| c@d | f2 | l2 |
+-------+------+------+
3 rows in set (0.00 sec)
mysql> DELETE t1 FROM test t1, test t2
-> WHERE t1.email = t2.email
-> AND t1.fn > t2.fn
-> AND t1.ln > t2.ln;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM test;
+-------+------+------+
| email | fn | ln |
+-------+------+------+
| a@b | f1 | l1 |
| c@d | f2 | l2 |
+-------+------+------+
2 rows in set (0.00 sec)
ALTER TABLE table_name RENAME TO table_name_bak;
CREATE TABLE table_name AS SELECT * FROM table_name_bak LIMIT 0;
ALTER TABLE table_name ADD PRIMARY KEY (email);
INSERT IGNORE INTO table_name SELECT * FROM table_name_bak;