我有一个这样的数据库:
users
id name email phone
1 bill bill@fakeemail.com
2 bill bill@fakeemail.com 123456789
3 susan susan@fakeemail.com
4 john john@fakeemail.com 123456789
5 john john@fakeemail.com 987654321
我想根据电子邮件字段合并被视为重复的记录。
试图弄清楚如何使用以下注意事项。
具有最高ID的号码(有关示例,请参见john@fakeemail.com行。)
这是我尝试过的查询:
DELETE FROM users WHERE users.id NOT IN
(SELECT grouped.id FROM (SELECT DISTINCT ON (email) * FROM users) AS grouped)
获取语法错误。
我正在尝试将数据库转换为此,我无法找出正确的查询:
users
id name email phone
2 bill bill@fakeemail.com 123456789
3 susan susan@fakeemail.com
5 john john@fakeemail.com 987654321
答案 0 :(得分:1)
以下是使用删除联接的一种选择:
DELETE
FROM users
WHERE id NOT IN (SELECT id
FROM (
SELECT CASE WHEN COUNT(*) = 1
THEN MAX(id)
ELSE MAX(CASE WHEN phone IS NOT NULL THEN id END) END AS id
FROM users
GROUP BY email) t);
此删除的逻辑如下:
id
值最高的记录(其中也定义了电话)之外的所有内容。答案 1 :(得分:1)
这是一个解决方案,它将为您提供结果表中每个用户每个字段的最新数据,从而满足您的第二个条件以及第一个和第三个条件。根据{{1}}上的group_concat_max_len
条件,它可以处理尽可能多的重复项。它使用GROUP_CONCAT
为每个用户准备一个字段的所有值的列表,并对其进行排序,以使最新值在前。然后使用SUBSTRING_INDEX
提取该列表中的第一个值,这是最新的。此解决方案使用CREATE TABLE ... SELECT
命令创建一个新的GROUP_CONCAT
表,然后users
替换旧表并将新表重命名为DROP
。
users
输出:
CREATE TABLE users
(`id` int, `name` varchar(5), `email` varchar(19), `phone` int)
;
INSERT INTO users
(`id`, `name`, `email`, `phone`)
VALUES
(1, 'bill', 'bill@fakeemail.com', 123456789),
(2, 'bill', 'bill@fakeemail.com', NULL),
(3, 'susan', 'susan@fakeemail.com', NULL),
(4, 'john', 'john@fakeemail.com', 123456789),
(5, 'john', 'john@fakeemail.com', 987654321)
;
CREATE TABLE newusers AS
SELECT id
, SUBSTRING_INDEX(names, ',', 1) AS name
, email
, SUBSTRING_INDEX(phones, ',', 1) AS phone
FROM (SELECT id
, GROUP_CONCAT(name ORDER BY id DESC) AS names
, email
, GROUP_CONCAT(phone ORDER BY id DESC) AS phones
FROM users
GROUP BY email) u;
DROP TABLE users;
RENAME TABLE newusers TO users;
SELECT * FROM users