【问题标题】:MySQL creates new rows instead of updating when using the INSERT INTO SELECT ... ON DUPLICATE KEY UPDATE ... SQL StatementMySQL 在使用 INSERT INTO SELECT ... ON DUPLICATE KEY UPDATE ... SQL 语句时创建新行而不是更新
【发布时间】:2018-09-03 07:01:18
【问题描述】:

我遇到了这个查询的问题:

INSERT INTO unit_storage (user_id,diagram_id,amount)
SELECT uf.user_id,
       uf.diagram_id,
       uf.amount
FROM unit_factory uf
WHERE uf.production_finish_time < /*current unix epoch seconds*/
  AND uf.user_id = /*provided user id*/ ON DUPLICATE KEY
  UPDATE unit_storage.amount=unit_storage.amount+uf.amount

让我们从正在发生的例子开始,我想要的效果是什么……

正如您可能从比较值中猜到的那样,production_finish_time 是整数列,其中以秒为单位的时间标记了某个日期。

查看 unit_factory 表行:

+-----+----------+-------------+---------+-------------------------+--+
| id  | user_id  | diagram_id  | amount  | production_finish_time  |  |
+-----+----------+-------------+---------+-------------------------+--+
|   7 |       10 |           2 |      1 |              1521472903 |  |
|   8 |       10 |           2 |      1 |              1521473704 |  |
|   9 |       10 |           2 |      1 |              1521473729 |  |
|  10 |       10 |           2 |     1  |              1521474294 |  |
+-----+----------+-------------+---------+-------------------------+--+

运行查询后,unit_storage 表成为 unit_factory 表的副本:

+-----+----------+-------------+---------+--+
| id  | user_id  | diagram_id  | amount  |  |
+-----+----------+-------------+---------+--+
|  16 |       10 |           2 |      1 |  |
|  17 |       10 |           2 |      1 |  |
|  18 |       10 |           2 |      1 |  |
|  19 |       10 |           2 |     1  |  |
+-----+----------+-------------+---------+--+

而我需要的结果是:

+-----+----------+-------------+---------+--+
| id  | user_id  | diagram_id  | amount  |  |
+-----+----------+-------------+---------+--+
|  16 |       10 |           2 |      4 |  |
+-----+----------+-------------+---------+--+

对于所需结果的正确查询是什么?

编辑

根据要求,两个表的索引:

--
-- Indexes for table `unit_storage`
--
ALTER TABLE `unit_storage`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `unit_factory`
--
ALTER TABLE `unit_factory`
  ADD PRIMARY KEY (`id`);

【问题讨论】:

  • 发布表创建语句。我们需要了解 PK 和 UK。
  • 我已经用索引创建语句更新了这个问题。

标签: mysql sql duplicates sql-update sql-insert


【解决方案1】:

要触发on duplicate key,必须有一个键:

ALTER TABLE unit_storage ADD CONSTRAINT key1 UNIQUE (user_id, diagram_id)

这是SQL Fiddle 上的一个工作示例。

【讨论】:

  • 谢谢你们。我认为这个答案的解决方案更加简洁和高效,我接受了这个答案。
【解决方案2】:
INSERT INTO unit_storage (user_id,diagram_id,amount)
SELECT Min(uf.user_id),
       Min(uf.diagram_id),
       sum(uf.amount)
FROM unit_factory uf
WHERE uf.production_finish_time < /*current unix epoch seconds*/
  AND uf.user_id = /*provided user id*/ ON DUPLICATE KEY
Group by uf.user_id,
       uf.diagram_id
  UPDATE unit_storage.amount=unit_storage.amount+uf.amount

【讨论】:

    猜你喜欢
    • 2011-01-29
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    相关资源
    最近更新 更多