Слияние записей SQL - PullRequest
       3

Слияние записей SQL

1 голос
/ 05 апреля 2011

эй, я не уверен, что это правильное место, чтобы спросить это, но у меня проблемы с моим сценарием.я пытаюсь сделать слияние базы данных с PHP, единовременное слияние.То, что я делаю, - это захват списка всех уникальных названий книги, затем поиск по этим названиям, поиск книг с таким названием и группирование по типам, затем поиск по этому результату, поиск книг с таким уникальным названием и типом, повторение процесса сАвторские права и издатели.главная проблема в том, что это занимает так много времени ожидания сервера MySQL.Есть ли лучший способ сделать это, возможно, с SQL?

Пример слияния может быть следующим:

INSERT INTO books (1, 'Some Book', 'Penguin Publishing', '2005', 1);
INSERT INTO books (2, 'Some Book', 'Penguin Publishing', '2005', 1);
INSERT INTO books (3, 'Some Book 2', 'Penguin Publishing', '2005', 1);
INSERT INTO books (4, 'Some Book 2', 'Lion Publishing', '2005', 1);
INSERT INTO books (5, 'Some Book 2', 'Penguin Publishing', '2005', 2);
INSERT INTO books (6, 'Some Book 2', 'Penguin Publishing', '2005', 2);
INSERT INTO books (7, 'Somebody', 'Lion Publishing', '2005', 1);
INSERT INTO books (8, 'Somebody', 'Lion Publishing', '2007', 1);
INSERT INTO books (9, 'Somebody', 'Penguin Publishing', '2005', 1);

Идентификаторы 1 и 2 должны объединиться, потому что они имеют 1) одинаковый заголовок 2)тот же material_type_id 3) то же авторское право и 4) тот же издатель.

Есть ли способ достичь этого с помощью PURE SQL или с незначительным PHP?

Вот моя структура данных:

CREATE TABLE books (
  id int(11) NOT NULL AUTO_INCREMENT,
  title varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  publisher varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  copyright varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  material_type_id int(11) DEFAULT NULL
  PRIMARY KEY (id),
  FULLTEXT KEY title (title)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

РЕДАКТИРОВАТЬ Наверное, я забыл упомянуть кое-что действительно важное.Я не могу просто использовать запрос GROUP, потому что мне нужно использовать идентификаторы.У меня есть другая таблица с именем 'Items', в которой есть поле book_id.Если я просто сгруппирую записи, я получу осиротевшие предметы.Мне нужен способ разбить запрос заказа, поэтому я получаю результат, подобный следующему:

id | title | publisher | copyright | material_type_id
-----------------------------------------------------
1  'Some Book' 'Penguin Publishing' '2005' 1
2  'Some Book' 'Penguin Publishing' '2005' 1
-----------------------------------------------------
5  'Some Book 2' 'Penguin Publishing' '2005' 2
6  'Some Book 2' 'Penguin Publishing' '2005' 2
-----------------------------------------------------
3  'Some Book 2' 'Penguin Publishing' '2005' 1
-----------------------------------------------------

Потому что тогда я могу выполнить такой запрос для первой группы:

UPDATE items SET book_id = 1 WHERE book_id IN (1, 2)

Надеюсь, это имеет смысл.Мне действительно сложно объяснить.Спасибо за вашу помощь и терпение.

1 Ответ

1 голос
/ 05 апреля 2011

В этом запросе хранятся все, кроме одной копии (с минимальным идентификатором) книги с учетом дублирующих правил.

DELETE FROM A
using books A
join (select title,publisher,material_type_id,copyright, MIN(id) keep
    from books
    group by title,publisher,material_type_id,copyright
    having count(*) > 1) B
    on A.title=B.title
       and A.publisher=B.publisher
       and A.material_type_id=B.material_type_id
       and A.copyright=B.copyright
       and A.id <> B.keep;

ДО , запустив вышеописанное, сначала переместите записи элементов (формально не проверено)

UPDATE items
join books A on A.id = items.book_id
join (select title,publisher,material_type_id,copyright, MIN(id) keep
    from books
    group by title,publisher,material_type_id,copyright
    having count(*) > 1) B
    on A.title=B.title
       and A.publisher=B.publisher
       and A.material_type_id=B.material_type_id
       and A.copyright=B.copyright
       and A.id <> B.keep
set items.book_id = B.keep
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...