Обновить дубликаты адресов электронной почты в таблице базы данных mysql - PullRequest
0 голосов
/ 25 марта 2020

У меня огромная база данных, в моей пользовательской таблице почти строка из 10 тыс. Строк, а также 2700 дублированных адресов электронной почты.

По существу, приложение не ограничивало пользователей от регистрации их учетных записей с одним и тем же адресом электронной почты снова и снова. Я убрал несколько из них - более 2 раз - вручную, их было немного, но есть 2700 адресов электронной почты с повторяющимся значением, которые встречаются как минимум 2 раза. Поэтому я хочу обновить дубликаты адресов электронной почты и изменить адрес электронной почты с меньшим идентификатором на что-то вроде «email@mail.com» на «1email@mail.com», в основном добавив «1» к началу всех дублирующих адресов электронной почты. Я могу выбрать и отобразить дубликаты адресов электронной почты, но не смог найти способ обновить только один из адресов электронной почты, а другой оставить нетронутым.

Моя структура таблицы выглядит как id username email password.

Ответы [ 2 ]

2 голосов
/ 25 марта 2020
WITH cte AS ( SELECT id, 
                     email, 
                     ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) rn
              FROM sourcetable )
UPDATE sourcetable src, cte
SET src.email = CONCAT(rn - 1, src.email)
WHERE src.id = cte.id
  AND cte.rn > 1;

скрипка


Я хочу обновить дубликаты адресов электронной почты и изменить адрес электронной почты с меньшим идентификатором номером

В этом случае порядок в оконной функции должен быть обратным:

WITH cte AS ( SELECT id, 
                     email, 
                     ROW_NUMBER() OVER (PARTITION BY email ORDER BY id DESC) rn
              FROM sourcetable )
UPDATE sourcetable src, cte
SET src.email = CONCAT(rn - 1, src.email)
WHERE src.id = cte.id
  AND cte.rn > 1;

скрипка

2 голосов
/ 25 марта 2020

Если у вас нет MySQL 8:

Здесь я просто добавляю id строки к адресу электронной почты:

UPDATE my_table JOIN (
    SELECT email, MAX(id) AS max_id, COUNT(*) AS cnt FROM my_table
    GROUP BY email
    HAVING cnt > 1
) sq ON my_table.email = sq.email AND my_table.id <> sq.max_id
SET my_table.email = CONCAT( my_table.id, my_table.email)
;

См. DB -Fiddle

Внутренний запрос:

SELECT email, MAX(id) AS max_id, COUNT(*) AS cnt FROM my_table
GROUP BY email
HAVING cnt > 1

ищет все дублирующиеся электронные письма (то есть существует более одной строки с одним и тем же адресом электронной почты) и вычисляет строку максимальное значение id для каждого адреса электронной почты. Для демонстрационных данных в моей демонстрации DB-Fiddle будет возвращено следующее:

| email            | max_id | cnt |
| ---------------- | ------ | --- |
| emaila@dummy.com | 3      | 3   |
| emailb@dummy.com | 5      | 2   |

Приведенный выше внутренний запрос называется таблицей sq.

Теперь, если я присоединюсь my_table с приведенным выше запросом следующим образом:

SELECT my_table.* from my_table join (
  SELECT email, MAX(id) AS max_id, COUNT(*) AS cnt FROM my_table
    GROUP BY email
    HAVING cnt > 1
) sq on my_table.email = sq.email and my_table.id <> sq.max_id

Я получаю:

| id  | email            |
| --- | ---------------- |
| 1   | emaila@dummy.com |
| 2   | emaila@dummy.com |
| 4   | emailb@dummy.com |

, потому что я выбираю из my_table все строки, которые имеют повторяющиеся адреса электронной почты (условие my_table.email = sq.email, кроме для строк, которые имеют наибольшее значение id для каждого адреса электронной почты (условие my_table.id <> sq.max_id).

Это идентификаторы из вышеуказанного объединения, чьи адреса электронной почты должны быть изменены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...