【问题标题】:INSERT SELECT ON DUPLICATE not updatingINSERT SELECT ON DUPLICATE 不更新
【发布时间】:2013-11-15 02:33:30
【问题描述】:

  1. 我想在TABLE_A 中基于CRITERIA X 插入一列SUM 并插入TABLE_B.total_x
  2. 我想在TABLE_A 中基于CRITERIA Y 插入一列SUM 并插入TABLE_B.total_y
  3. 问题:第 2 步没有更新 TABLE_B.total_y

TABLE_A:数据

| year | month | type | total |
---------------------------------------
| 2013 | 11    | down | 100   |
| 2013 | 11    | down | 50    |
| 2013 | 11    | up   | 60    |
| 2013 | 10    | down | 200   |
| 2013 | 10    | up   | 15    |
| 2013 | 10    | up   | 9     |

TABLE_B:结构

CREATE TABLE `TABLE_B` (
    `year` INT(4) NULL DEFAULT NULL,
    `month` INT(2) UNSIGNED ZEROFILL NULL DEFAULT NULL,
    `total_x` INT(10) NULL DEFAULT NULL,
    `total_y` INT(10) NULL DEFAULT NULL,
    UNIQUE INDEX `unique` (`year`, `month`)
)

SQL:CRITERIA_X

INSERT INTO TABLE_B (
 `year`, `month`, `total_x`
)
SELECT 
  t.`year`, t.`month`,
  SUM(t.`total`) as total_x
FROM TABLE_A t
WHERE
  t.`type` = 'down'
GROUP BY
  t.`year`, t.`month`
 ON DUPLICATE KEY UPDATE
  `total_x` = total_x
;

SQL:CRITERIA_Y

INSERT INTO TABLE_B (
 `year`, `month`, `total_y`
)
SELECT 
  t.`year`, t.`month`,
  SUM(t.`total`) as total_y
FROM TABLE_A t
WHERE
  t.`type` = 'up'
GROUP BY
  t.`year`, t.`month`
 ON DUPLICATE KEY UPDATE
  `total_y` = total_y
;

第二个 SQL (CRITERIA_Y) 未按预期更新 total_y为什么?

【问题讨论】:

    标签: mysql sql select insert on-duplicate-key


    【解决方案1】:

    我会用另一种方式来做

    insert into TABLE_B (year, month, total_x, total_y)
    select year, month
         , sum (case [type] when 'down' then [total] else 0 end) [total_x]
         , sum (case [type] when 'up' then [total] else 0 end) [total_y]
    from TABLE_A
    group by [year], [month]
    

    或者使用两个子查询的方式是

    insert into TABLE_B (year, month, total_x, total_y)
    select coalesce(t1.year, t2.year) year
         , coalesce(t1.month, t2.month) month
         , t1.total_x total_x
         , t2.total_y total_y
    from (select year, month, sum(total) total_x
             from TABLE_A where [type]='down') t1 
    full outer join
         (select year, month, sum(total) total_y
             from TABLE_A where [type]='up') t2
         on t1.year = t2.year and t1.month = t2.month
    

    或者使用联合

    insert into TABLE_B (year, month, total_x, total_y)
    select year, month, sum(total_x), sum(total_y)
    from ( 
       select year, month, sum(total) total_x, 0 total_y
       from TABLE_A where [type]='down'
       group by year, month
       union
       select year, month, 0 total_x, sum(total) total_y
       from TABLE_A where [type]='up'
       group by year, month) t
    group by year, month  
    

    阅读关于 INSERT...ON DUPLICATE KEY UPDATE 的规范,我注意到了这一点:

    如果 ... 匹配多行,则仅更新一行。通常,您应该尽量避免在具有多个唯一索引的表上使用 ON DUPLICATE KEY UPDATE 子句。

    所以复合键的语法有点麻烦,我个人会避免使用它。

    【讨论】:

    • 我以前从未以这种方式进行过 SUM。让我看看它是否有效
    • 完美。这类似于我的想法,但不知道该怎么做。谢谢
    • 如果你能解释一下,我仍然会对为什么我这样做的方式不起作用感兴趣......
    • 子查询看起来很麻烦。联合似乎是实现通用目的的更好方法。但是 SUM(案例)似乎是一种非常好的捷径。我可能会更频繁地使用它。感谢您为答案添加更多解释。
    猜你喜欢
    • 2022-08-02
    • 2011-01-29
    • 2012-02-26
    • 2015-05-16
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多