在mysql中合并重复行

iovurdzv  于 2021-06-17  发布在  Mysql
关注(0)|答案(2)|浏览(360)

我有这样一个数据库:

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

我想根据email字段合并被认为是重复的记录。
试图找出如何使用以下注意事项。
基于重复电子邮件合并
如果一行有空值,则使用数据最多的行。
如果两行重复,但其他字段不同,则使用一行
拥有最高的身份证号码(参见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
kgsdhlau

kgsdhlau1#

下面是一个使用delete join的选项:

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 值,其中还定义了电话。

chy5wohz

chy5wohz2#

下面的解决方案将为结果表中每个用户的每个字段提供最新数据,从而满足第二个标准以及第一个和第三个标准。它将适用于尽可能多的副本,你有,取决于 group_concat_max_len 条件 GROUP_CONCAT . 它使用 GROUP_CONCAT 为每个用户准备一个字段所有值的列表,按最新值排在第一位进行排序。 SUBSTRING_INDEX 然后用于提取该列表中的第一个值,即最近的值。此解决方案使用 CREATE TABLE ... SELECT 命令创建新的 users 那就坐table吧 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

输出:

id  name    email                   phone
1   bill    bill@fakeemail.com      123456789
4   john    john@fakeemail.com      987654321
3   susan   susan@fakeemail.com     (null)

sqlfiddle演示

相关问题