关于重复密钥更新+子查询的Mysql

时间:2010-05-02 21:33:26

标签: mysql

使用此问题的答案:Need MySQL INSERT - SELECT query for tables with millions of records

new_table
    * date
    * record_id (pk)
    * data_field


INSERT INTO new_table (date,record_id,data_field)
    SELECT date, record_id, data_field FROM old_table
        ON DUPLICATE KEY UPDATE date=old_table.data, data_field=old_table.data_field;

我需要这个与group by一起工作并加入..所以编辑:

INSERT INTO new_table (date,record_id,data_field,value)
    SELECT date, record_id, data_field, SUM(other_table.value) as value FROM old_table JOIN other_table USING(record_id) GROUP BY record_id
        ON DUPLICATE KEY UPDATE date=old_table.data, data_field=old_table.data_field, value = value;

我似乎无法更新价值。如果我指定old_table.value,我会在字段列表错误中得到一个未定义的内容。

2 个答案:

答案 0 :(得分:7)

根据http://dev.mysql.com/doc/refman/5.0/en/insert-select.html

的文档
  

在ON DUPLICATE KEY UPDATE的值部分中,只要不在SELECT部分​​中使用GROUP BY,就可以引用其他表中的列。一个副作用是您必须在值部分中限定非唯一列名称。

因此,您无法使用select查询,因为它具有group by语句。你需要使用这个技巧。基本上,这会创建一个派生表供您查询。它可能效率不高,但它确实有效。

INSERT INTO new_table (date,record_id,data_field,value)
    SELECT date, record_id, data_field, value 
    FROM (
        SELECT date, record_id, data_field, SUM(other_table.value) as value 
        FROM old_table
        JOIN other_table
        USING(record_id)
        GROUP BY record_id
    ) real_query 
ON DUPLICATE KEY
    UPDATE date=real_query.date, data_field=real_query.data_field, value = real_query.value;

答案 1 :(得分:4)

在搜索更多内容时,我发现了一个相关的问题:“MySQL ON DUPLICATE KEY UPDATE with nullable column in unique key”。

答案是VALUES()可用于引用选择子查询中的列“值”。