2015-09-24 2 views
1

MySQL 5.6Обновить все строки, связанные с дубликатами другой таблицы

У нас есть две таблицы: cars и views.

Cars   Views 
---+-------  ---+------- 
id | desc  id | car_id 
---+-------  ---+------- 
1 | desc1  1 | 1 
2 | Desc1  2 | 2 
3 | desc2  3 | 3 

Проблема заключается с desc поля в таблице автомобилей. Эта строка должна была быть уникальной, но мы, к сожалению, позволили пользователям заполнить верхние значения, что привело нас к ситуации, когда (по приведенному выше примеру) было два дублированных строки: desc1 и Desc1.

Способ устранения: DELETE дублированные автомобили и сохранить только первый. Мы знаем, как с этим бороться.

Наша проблема возникает перед обновлением связанной таблицы, когда некоторые виды связаны с автомобилем, который имеет дублированный desc (например, автомобиль, который будет удален). Эти мнения должны быть обновлены назначаются на первый из дублированных автомобилей (в данном случае автомобиль ID # 1)

После UPDATE, мы хотели бы этот результат просмотров:

Views 
---+------- 
id | car_id 
1 | 1 
2 | 1 
3 | 3 

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

+0

является идентификатором дубликата всегда * выше *, а затем идентификатором реального ряда? как в вставленном после этого, в случае автоинкрементного столбца id? –

+0

Точно, дублирование, которое мы хотим удалить, это те, у которых есть более высокие идентификаторы. Мы хотим сохранить только один нижний идентификатор. – lisbonman

ответ

0

Решение будет заключаться в создании таблицы сопоставления с значениями до/после для описания id.

Результат должен выглядеть примерно так:

Before | After 
--------------- 
1  | 1 
2  | 1 
3  | 3 

Эта таблица может быть создана с чем-то вроде этого:

SELECT 
    cars.id AS before_id, 
    fixed.lowest_id AS after_id 
FROM cars 
JOIN (
    -- The lowest id value for each duplicate description 
    SELECT 
     MIN(id) AS lowest_id, 
     LOWER(desc) AS lower_desc 
    FROM cars 
    GROUP BY LOWER(desc) 
) fixed 
ON LOWER(cars.desc) = fixed.lower_desc 

Вы можете иметь ваши взгляды совпадают с этой таблицы отображения тянуть новый "correct" id значение.

0
UPDATE Views AS v 
JOIN (SELECT c1.id AS oldID, MIN(c2.id) AS newID 
     FROM Cars AS c1 
     JOIN Cars AS c2 ON LOWER(c1.desc) = LOWER(c2.desc) 
     HAVING oldID != newID) AS c 
    ON v.car_id = oldID 
SET v.car_id = newID 

Подзапрос находит первичный идентификатор для каждого идентификатора, который содержит дублирующее описание. Присоединение к таблице Views содержит информацию, необходимую для замены.

+0

Не следует ли встраивать любой подзапрос 'GROUP BY' для получения результатов сгруппированных и фильтрованных правильно? 'GROUP BY LOWER (c1.desc)' например? – Alex

+0

Не требуется группировка, нам просто нужно соединить каждый дубликат с его основным, что и в разделе 'ON'. Если есть более одного дубликата, группировка пропустит дополнительные функции. – Barmar

Смежные вопросы