ВСТУПИТИ В… ВИБІРИТЕ З… НА ДУПЛІКАТИ КЛЮЧУ ОНОВЛЕННЯ


116

Я роблю запит на вставку, де більшість багатьох стовпців потрібно буде оновити до нових значень, якщо унікальний ключ уже існував. Це щось подібне:

INSERT INTO lee(exp_id, created_by, 
                location, animal, 
                starttime, endtime, entct, 
                inact, inadur, inadist, 
                smlct, smldur, smldist, 
                larct, lardur, lardist, 
                emptyct, emptydur)
SELECT id, uid, t.location, t.animal, t.starttime, t.endtime, t.entct, 
       t.inact, t.inadur, t.inadist, 
       t.smlct, t.smldur, t.smldist, 
       t.larct, t.lardur, t.lardist, 
       t.emptyct, t.emptydur 
FROM tmp t WHERE uid=x
ON DUPLICATE KEY UPDATE ...; 
//update all fields to values from SELECT, 
//       except for exp_id, created_by, location, animal, 
//       starttime, endtime

Я не впевнений, яким UPDATEповинен бути синтаксис пропозиції. Як я посилаюся на поточний рядок із SELECTпункту?

Відповіді:


172

MySQL візьме на себе частину перед рівним посиланням на стовпці, названі в пункті INSERT INTO, а друга частина посилається на стовпці SELECT.

INSERT INTO lee(exp_id, created_by, location, animal, starttime, endtime, entct, 
                inact, inadur, inadist, 
                smlct, smldur, smldist, 
                larct, lardur, lardist, 
                emptyct, emptydur)
SELECT id, uid, t.location, t.animal, t.starttime, t.endtime, t.entct, 
       t.inact, t.inadur, t.inadist, 
       t.smlct, t.smldur, t.smldist, 
       t.larct, t.lardur, t.lardist, 
       t.emptyct, t.emptydur 
FROM tmp t WHERE uid=x
ON DUPLICATE KEY UPDATE entct=t.entct, inact=t.inact, ...

6
@dnagirl: Порада: не намагайтеся оновлювати жодну зі стовпців ПК, лише ті, які потребують оновлення, переходять до списку
lexu

45
Запропонований вами синтаксис працює, і обов'язкове значення t.є. Я також знайшов статтю про xaprb ( xaprb.com/blog/2006/02/21/flexible-insert-and-update-in-mysql ) , який використовує цей синтаксис: on duplicate key update b = values(b), c = values(c). Це також працює.
dnagirl

9
Примітка. Це не спрацює, якщо в операторі SELECT є пункт GROUP BY
JOHN

11
@john Що робити, якщо у заяві SELECT є пункт GROUP BY
Kathir,

2
dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html говорить `у MySQL 5.6.4 та пізніших версіях, ВСТАВИТИ ... ВИБІР ДЛЯ ДУПЛІКАТУВАННЯ КЛЮЧОВОГО ОНОВЛЕННЯ заяви позначені як небезпечні для реплікації на основі висловлювань ... Крім того, починаючи з MySQL 5.6.6, ВСТАВКА ... ПРО ДУПЛІКУВАННЯ КЛЮЧОВОГО ОБНОВЛЕННЯ проти таблиці, що має більше ніж один унікальний або первинний ключ, також позначається як небезпечна.`
Abdul Muneer

51

Хоча я дуже спізнююсь із цим, але побачивши деякі законні запитання для тих, хто хотів використати INSERT-SELECTзапит із GROUP BYзастереженням, я придумав цю проблему .

Беручи далі відповідь Маркуса Адамса та бухгалтерський облік GROUP BYу ній, саме так я вирішував би проблему, використовуючиSubqueries in the FROM Clause

INSERT INTO lee(exp_id, created_by, location, animal, starttime, endtime, entct, 
                inact, inadur, inadist, 
                smlct, smldur, smldist, 
                larct, lardur, lardist, 
                emptyct, emptydur)
SELECT sb.id, uid, sb.location, sb.animal, sb.starttime, sb.endtime, sb.entct, 
       sb.inact, sb.inadur, sb.inadist, 
       sb.smlct, sb.smldur, sb.smldist, 
       sb.larct, sb.lardur, sb.lardist, 
       sb.emptyct, sb.emptydur
FROM
(SELECT id, uid, location, animal, starttime, endtime, entct, 
       inact, inadur, inadist, 
       smlct, smldur, smldist, 
       larct, lardur, lardist, 
       emptyct, emptydur 
FROM tmp WHERE uid=x
GROUP BY location) as sb
ON DUPLICATE KEY UPDATE entct=sb.entct, inact=sb.inact, ...

8
Це правильна відповідь на запити з COUNT, GROUP тощо. Дякую.
Костанос

Дякую тобі, чувак! Мені дуже сподобався такий підхід, особливо тому, що він дозволяє мені створити такий механізм, як Постійний запит - те, що робить InfluxDB.
Miere

1
Ви можете також використовувати поле = VALUES (поле) в дублікаті поновлення , як у відповіді на stackoverflow.com/questions/16935896 / ...
Ерік Melkersson
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.