MySQLi - обработка дубликатов
Таблицы или наборы результатов иногда содержат повторяющиеся записи. Иногда это разрешено, но иногда требуется остановить повторяющиеся записи. Иногда требуется выявить повторяющиеся записи и удалить их из таблицы. В этой главе описывается, как предотвратить появление повторяющихся записей в таблице и как удалить уже существующие повторяющиеся записи.
Предотвращение дублирования в таблице
Вы можете использовать PRIMARY KEY или же UNIQUEИндексируйте таблицу с соответствующими полями, чтобы избежать дублирования записей. Возьмем один пример: следующая таблица не содержит такого индекса или первичного ключа, поэтому она допускает дублирование записей для first_name и last_name.
CREATE TABLE person_tbl (
first_name CHAR(20),
last_name CHAR(20),
sex CHAR(10)
);
Чтобы предотвратить создание в этой таблице нескольких записей с одинаковыми значениями имени и фамилии, добавьте в ее определение ПЕРВИЧНЫЙ КЛЮЧ. Когда вы это делаете, также необходимо объявить индексированные столбцы NOT NULL, потому что PRIMARY KEY не допускает значений NULL -
CREATE TABLE person_tbl (
first_name CHAR(20) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10),
PRIMARY KEY (last_name, first_name)
);
Наличие уникального индекса в таблице обычно вызывает ошибку, если вы вставляете в таблицу запись, которая дублирует существующую запись в столбце или столбцах, определяющих индекс.
Использовать INSERT IGNORE скорее, чем INSERT. Если запись не дублирует существующую, MySQLi вставляет ее как обычно. Если запись является дубликатом, ключевое слово IGNORE сообщает MySQLi о необходимости отбросить ее без вывода ошибки.
Следующий пример не приводит к ошибке и в то же время не вставляет повторяющиеся записи.
mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
-> VALUES( 'Jay', 'Thomas');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
-> VALUES( 'Jay', 'Thomas');
Query OK, 0 rows affected (0.00 sec)
Использовать REPLACEа не ВСТАВИТЬ. Если запись новая, она вставляется так же, как с INSERT. Если это дубликат, новая запись заменяет старую -
mysql> REPLACE INTO person_tbl (last_name, first_name)
-> VALUES( 'Ajay', 'Kumar');
Query OK, 1 row affected (0.00 sec)
mysql> REPLACE INTO person_tbl (last_name, first_name)
-> VALUES( 'Ajay', 'Kumar');
Query OK, 2 rows affected (0.00 sec)
INSERT IGNORE и REPLACE следует выбирать в соответствии с поведением обработки дубликатов, которое вы хотите выполнить. INSERT IGNORE сохраняет первую из набора повторяющихся записей и отбрасывает остальные. REPLACE сохраняет последние дубликаты и удаляет все более ранние.
Еще один способ обеспечить уникальность - добавить в таблицу УНИКАЛЬНЫЙ индекс, а не ПЕРВИЧНЫЙ КЛЮЧ.
CREATE TABLE person_tbl (
first_name CHAR(20) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10)
UNIQUE (last_name, first_name)
);
Подсчет и идентификация дубликатов
Ниже приведен запрос для подсчета повторяющихся записей с first_name и last_name в таблице.
mysql> SELECT COUNT(*) as repetitions, last_name, first_name
-> FROM person_tbl
-> GROUP BY last_name, first_name
-> HAVING repetitions > 1;
Этот запрос вернет список всех повторяющихся записей в таблице person_tbl. В общем, чтобы определить наборы значений, которые дублируются, выполните следующие действия:
Определите, какие столбцы содержат значения, которые могут дублироваться.
Перечислите эти столбцы в списке выбора столбцов вместе с COUNT (*).
Также укажите столбцы в предложении GROUP BY.
Добавьте предложение HAVING, которое исключает уникальные значения, требуя, чтобы количество групп было больше единицы.
Удаление дубликатов из результата запроса:
Вы можете использовать DISTINCT вместе с оператором SELECT, чтобы узнать уникальные записи, доступные в таблице.
mysql> SELECT DISTINCT last_name, first_name
-> FROM person_tbl
-> ORDER BY last_name;
Альтернативой DISTINCT является добавление предложения GROUP BY с именами выбранных столбцов. Это дает эффект удаления дубликатов и выбора только уникальных комбинаций значений в указанных столбцах -
mysql> SELECT last_name, first_name
-> FROM person_tbl
-> GROUP BY (last_name, first_name);
Удаление дубликатов с помощью замены таблицы
Если у вас есть повторяющиеся записи в таблице, и вы хотите удалить все повторяющиеся записи из этой таблицы, то вот процедура:
mysql> CREATE TABLE tmp SELECT last_name, first_name, sex
-> FROM person_tbl;
-> GROUP BY (last_name, first_name);
mysql> DROP TABLE person_tbl;
mysql> ALTER TABLE tmp RENAME TO person_tbl;
Простой способ удалить повторяющиеся записи из таблицы - добавить в эту таблицу ИНДЕКС или КЛЮЧ PRIMAY. Даже если эта таблица уже доступна, вы можете использовать эту технику для удаления повторяющихся записей, и вы будете в безопасности и в будущем.
mysql> ALTER IGNORE TABLE person_tbl
-> ADD PRIMARY KEY (last_name, first_name);