Mysql 插入选择重复,不更新

Mysql 插入选择重复,不更新,mysql,sql,select,insert,on-duplicate-key,Mysql,Sql,Select,Insert,On Duplicate Key,短期 我想根据标准X对表a中的一列进行求和并将其插入表B。总计 我想根据标准Y对表a中的一列进行求和并插入表B。总计 问题:步骤2未更新表\u B.总计\u y LONG 表A:数据 | year | month | type | total | --------------------------------------- | 2013 | 11 | down | 100 | | 2013 | 11 | down | 50 | | 2013 | 11 | up

短期

  • 我想根据
    标准X
    表a
    中的一列进行
    求和
    并将其插入
    表B。总计
  • 我想根据
    标准Y
    表a
    中的一列进行
    求和
    并插入
    表B。总计
  • 问题:步骤2未更新
    表\u B.总计\u y
  • LONG

    表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     |
    
    表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\ux

    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(条件Y)未按预期更新
    total_Y
    为什么?

    我会用另一种方式

    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子句


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

    我以前从未用这种方式求和。让我看看它是否完美。这和我想做的很相似,但我不知道怎么做。谢谢如果你能解释的话,我仍然会对为什么我的方法不起作用感兴趣…子查询看起来很麻烦。对于一般目的而言,工会似乎是更好的方式。但是求和似乎是一个很好的捷径。我可能会更经常地使用它。谢谢你为答案添加了更多的解释。