Обновите последующие повторяющиеся значения полей в MySQL - PullRequest
0 голосов
/ 27 июня 2011

У меня есть следующая схема:

id | order_ref | description | price

В настоящее время у меня есть следующая проблема:

1 | 34567 | This is the description | 19.99
2 | 34567 | This is the description | 13.99

Это было связано с тем, что я импортировал данные с дублированием описания для каждого элемента. Есть ли способ сохранить первый ряд, а затем ОБНОВИТЬ описание последующих (до 20 строк) до «КАК ВЫШЕ»?

1 | 34567 | This is the description | 19.99
2 | 34567 | - AS ABOVE - | 13.99

Спасибо

------- ОБНОВЛЕНО

UPDATE documents_orders_breakdown
SET `desc` = '- AS ABOVE -'
WHERE NOT id IN (SELECT id
             FROM documents_orders_breakdown AS D
             WHERE D.`desc` <> `desc`
             ORDER BY D.id
             LIMIT 1)

Но это возвращает [Err] 1235 - Эта версия MySQL еще не поддерживает 'LIMIT & IN / ALL / ANY / SOME subquery'

-------- ОБНОВЛЕНО

UPDATE documents_orders_breakdown
SET `desc` = '- AS ABOVE -'
WHERE NOT id IN (SELECT MIN(id)
                 FROM documents_orders_breakdown AS t
                 WHERE t.`desc` = `desc`)

Это теперь возвращает [Err] 1093 - Вы не можете указать целевую таблицу 'documents_orders_breakdown' для обновления в предложении FROM

Ответы [ 3 ]

1 голос
/ 27 июня 2011

Если это разовая вещь, производительность не является большой проблемой.Вы можете запустить UPDATE для всех записей, которые не возвращаются SELECT с ПРЕДЕЛОМ 1.

UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT id
                 FROM the_table t
                 WHERE t.description = the_table.description
                 ORDER BY t.id
                 LIMIT 1)

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


Поскольку вы не можете использовать LIMIT в подзапросах, вы можете обойти это, используя агрегатную функцию MIN:

UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT MIN(id)
                 FROM the_table t
                 WHERE t.description = the_table.description)

(Будем надеяться, что вы можете смешатьMIN и подзапросы;)


Очевидно, вы не можете ВЫБРАТЬ из таблицы, которую вы ОБНОВЛЯЕТЕ в MySQL .Обходной путь должен использовать неявную временную таблицу.Это плохо сказывается на производительности, но, опять же, учитывая, что это разовая вещь, это не большая проблема.

UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT m FROM (SELECT MIN(id) AS m
                 FROM the_table t
                 WHERE t.description = the_table.description) AS temp)
0 голосов
/ 28 июня 2011

Комментарий Освальда относительно порядка (или его отсутствия) строк очень важен.У вас нет garuntee, period , что несортированные строки, выбранные из этой таблицы, будут в ожидаемом вами порядке.Это означает, что если вы не укажете существующий в табличном порядке каждый раз , вещи могут быть помечены «КАК ВЫШЕ», даже если это не отражает реальность.Кроме того, ни одно из предоставленных решений до настоящего времени не будет правильно работать с какими-либо несоответствующими записями.
В целом, это больше похоже на проблему проектирования базы данных (в частности, на проблему нормализации), чем на проблему запроса.
В идеале, описания должны быть извлечены в некоторый мастер данных (вместе с необходимыми идентификаторами).Затем выбор используемого описания остается за выполнением команды SELECT.Это дает дополнительное преимущество, заключающееся в обеспечении безопасности «КАК ВЫШЕ» для изменений в упорядочении.

Таким образом, если предположить, что каждый экземпляр столбца order_ref должен иметь свое описание (за исключением бита «ВЫШЕ»),Таблицы могут быть реорганизованы следующим образом:

id | order_ref | price 
======================= 
 1 | 34567     | 19.99  
 2 | 34567     | 13.99  

и

order_ref_fk | description  
==========================================
34567        | "This is the description"

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

Если вы настаиваете на этомin-db, вы можете написать SELECT в таком ключе:

SELECT Orders.id, Orders.order_ref, Orders.price,
       COALESCE(Dsc.description, 'AS ABOVE')
FROM Orders
LEFT JOIN (Description
           JOIN (SELECT order_ref, MIN(id) AS id
                 FROM Orders
                 GROUP BY order_ref) Ord
             ON Ord.order_ref = Description.order_ref_fk) Dsc
        ON Dsc.order_ref_fk = Orders.order_ref
           AND Dsc.id = Orders.id
ORDER BY Orders.order_ref, Orders.id
0 голосов
/ 27 июня 2011

Реляционные базы данных не имеют понятия последующих . Записи в таблице расположены не в определенном порядке. Если вы не указали порядок в запросе SELECT, вы должны предположить, что записи извлекаются в порядке, который вы не ожидаете.

...