2010-03-18 2 views
95

Я делаю запрос вставки, в котором большинство новых столбцов необходимо обновить до новых значений, если уже существует уникальный ключ. Это идет что-то вроде этого:INSERT INTO ... SELECT FROM ... ON DUPLICATE KEY UPDATE

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?

ответ

125

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, ... 
+5

@dnagirl: ** TIP **: не пытайтесь обновите любой из столбцов PK, только те, которые нуждаются в обновлении, перейдите в список – lexu

+37

. Предлагаемые синтаксисы и 't.' необходимы. Я также нашел статью о xaprb (http://www.xaprb.com/blog/2006/02/21/flexible-insert-and-update-in-mysql/), которая использует этот синтаксис: 'on duplicate key update b = значения (b), c = значения (c) '. Это также работает. – dnagirl

+7

Примечание: Это не будет работать, если инструкция SELECT имеет предложение GROUP BY – joHN

28

Хотя я очень поздно это, но после того, как видим некоторые закономерные вопросы для тех, кто хочет использовать 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, ... 
+6

Это правильный ответ для запросов с помощью COUNT, GROUP и т. Д. Спасибо. – Kostanos

+0

Большое вам спасибо, чувак! Мне очень понравился этот подход, особенно потому, что он позволяет мне создать такой механизм, как Continuous Query, что делает InfluxDB. – Miere

+0

Рад слышать, что – iConfused