【问题标题】:Update / Merge table with summing values使用求和值更新/合并表
【发布时间】:2014-04-19 08:19:53
【问题描述】:

我有一个架构:

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) 对的记录数量来更新数量字段。喜欢在操作之后:

  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);

两次插入完成时会发生重复:

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

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

可能在插入两个表的过程中可以解决..

【问题讨论】:

  • 为什么没有在id、句号上定义主键?您现在有多个具有相同 id 和 period 的记录。您无法使用所有这些的总和仅更新其中一个。您可以做的是创建另一个表来合并总和。然后您可以删除第一个并将所有数据插入其中。但是如果你不定义主键,那么你可能会一遍又一遍地遇到这种情况。
  • 是的,创建一个新表可以解决它,但我做不到。我没有创建这样设计的表:(
  • 如果有像 xid 这样的唯一键,我该怎么办?
  • 同一张表上的唯一键?它可能会有所帮助,但这取决于您实际想要获得的内容......您有 2 行,id=1000 和 period=1。您想要一个数量=600 并删除另一个吗?您是否都想要金额 = 600(对此表示怀疑)?或者还有什么?
  • 我的意思是一个额外的字段 xid 在相同的情况下是唯一的。

标签: sql oracle merge sql-update


【解决方案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、句点键以避免将来出现问题)。

【讨论】:

  • 我无法创建额外的表 :(
  • 好久没用Oracle了。你不能创建一个内存表吗?我的意思是,当您提交交易时需要注意的事项。
  • 问题是你不能用聚合从同一个表中读取的值更新表......你不能在 SQL 中(但你可以使用客户端应用程序或存储过程来做到这一点通过在行上循环)。您可以在 SQL 中做的是使用辅助临时表来放置聚合结果。您仍然没有清楚地解释您希望原始多行具有相同的 id 和句点会发生什么。
猜你喜欢
  • 2016-09-02
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
相关资源
最近更新 更多