使用求和值更新/合并表

时间:2014-04-19 08:19:53

标签: sql oracle merge sql-update

我有一个架构:

http://sqlfiddle.com/#!4/e9917/1

CREATE TABLE test_table (
  id NUMBER,
  period NUMBER,
  amount NUMBER
);

INSERT INTO test_table VALUES (1000, 1, 100);
INSERT INTO test_table VALUES (1000, 1, 500);
INSERT INTO test_table VALUES (1001, 1, 200);
INSERT INTO test_table VALUES (1001, 2, 300);
INSERT INTO test_table VALUES (1002, 1, 900);
INSERT INTO test_table VALUES (1002, 1, 250);

我想通过添加具有相同(id,period)对的记录数来更新金额字段。喜欢在op:

之后
  ID|  period|   amount
1000         1      600
1001         1      200
1001         2      300
1002         1     1150 

我无法弄清楚:(

编辑:

在实际情况中,此表由其他2个表的插入操作填充:

CREATE TABLE some_table1(
  id NUMBER,
  period NUMBER,
  amount NUMBER
);

INSERT INTO some_table1 VALUES (1000, 1, 100);
INSERT INTO some_table1 VALUES (1000, 1, 500);
INSERT INTO some_table1 VALUES (1001, 1, 200);
INSERT INTO some_table1 VALUES (1001, 2, 300);
INSERT INTO some_table1 VALUES (1002, 1, 900);
INSERT INTO some_table1 VALUES (1002, 1, 250);

CREATE TABLE some_table2(
  id NUMBER,
  period NUMBER,
  amount NUMBER
);

INSERT INTO some_table2 VALUES (1000, 1, 30);
INSERT INTO some_table2 VALUES (1000, 1, 20);
INSERT INTO some_table2 VALUES (1001, 1, 15);
INSERT INTO some_table2 VALUES (1001, 2, 20);
INSERT INTO some_table2 VALUES (1002, 1, 50);
INSERT INTO some_table2 VALUES (1002, 1, 60);

完成两次插入时会出现Dublicates:

INSERT INTO TEST_TABLE (id,period,amount) SELECT id,period,amount from some_table1
INSERT INTO TEST_TABLE (id,period,amount) SELECT id,period,amount from some_table2

new sqlfiddle链接:http://sqlfiddle.com/#!4/cd45b/1

可以从两张桌子插入时解决..

1 个答案:

答案 0 :(得分:1)

像这样的脚本会做你想要的:

CREATE TABLE test_table_summary (
  id NUMBER,
  period NUMBER,
  amount NUMBER
);

INSERT INTO test_table_summary (id, period, amount)
SELECT id, period, SUM(amount) AS total_amount FROM test_table
GROUP BY id, period;

DELETE FROM test_table;

INSERT INTO test_table (id, period, amount)
SELECT id, period, total_amount FROM test_table_summary;

DROP TABLE test_table_summary;

但实际上您应该确定test_table是否具有主键以及总量或所有详细数据。对两者使用一个表都不是一个好的解决方案。

根据您添加的内容,我会说您可以使用Oracle MERGE INTO语句:

MERGE INTO test_table t
   USING (SELECT id, period, amount FROM some_table1) s
   ON (t.id=s.id AND t.period=s.period)
   WHEN MATCHED THEN UPDATE SET t.amount=t.amount+s.amount
   WHEN NOT MATCHED THEN INSERT (t.id, t.period, t.amount)
     VALUES (s.id, s.period, s.amount);

请注意......只有当test_table已经没有重复的id,期间行开始时,这才有效。因此,如果您的表格已经搞砸了,您仍然需要第一次正确地重新初始化它(并且可能添加一个唯一的ID,期间密钥以避免将来出现问题)。