質問

Short

  1. I want to SUM a column in TABLE_A based on CRITERIA X and insert into TABLE_B.total_x
  2. I want to SUM a column in TABLE_A based on CRITERIA Y and insert into TABLE_B.total_y
  3. Problem: Step 2 does not update TABLE_B.total_y

LONG

TABLE_A: Data

| 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: structure

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
;

The second SQL (CRITERIA_Y) does not update total_y as expected. WHY?

役に立ちましたか?

解決

I would do it another way

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]

Or using two subqueries way would be

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

Or using union

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  

Reading specs on INSERT...ON DUPLICATE KEY UPDATE, I noticed this:

If ... matches several rows, only one row is updated. In general, you should try to avoid using an ON DUPLICATE KEY UPDATE clause on tables with multiple unique indexes.

So syntax with composite key is kind of cumbersome, and I personally would avoid using it.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top