通过输入 sum(column) 值来更新记录

Posted

技术标签:

【中文标题】通过输入 sum(column) 值来更新记录【英文标题】:updating records by putting sum(column) value 【发布时间】:2019-03-11 17:01:47 【问题描述】:

我有这样的table1:

+-----+-----+------+
| cat | val | type |
+-----+-----+------+
| A   | 100 | c1   |
| H   | 25  | c2   |
| H   | 50  | c3   |
| H   | 30  | c2   |
| A   | 15  | c3   |
| H   | 10  | c1   |
| H   | 15  | c1   |
| B   | 10  | c4   |
| H   | 20  | c4   |
| H   | 15  | c3   |
+-----+-----+------+

我需要按类型将 sum(val) 组添加到仅属于每种类型的一个 H

所以我在按类型分组后说 table2 :

+-----+-----+
| cat | val |
+-----+-----+
| c1  | 125 |
| c2  | 55  |
| c3  | 80  |
| c4  | 30  |
+-----+-----+

我需要将 125 添加到 c1 类型的任何一个 H 值,将 55 添加到 c2 的任何一个 H 值,等等。如果 c1 没有 H,那么它应该创建该记录。

所以最后我们得到:

    +-----+-----+------+
    | cat | val | type |
    +-----+-----+------+
    | A   | 100 | c1   |
    | H   | 25  | c2   |
    | H   | 130 | c3   |
    | H   | 85  | c2   |
    | A   | 15  | c3   |
    | H   | 135 | c1   |
    | H   | 15  | c1   |
    | B   | 10  | c4   |
    | H   | 50  | c4   |
    | H   | 15  | c3   |
    +-----+-----+------+

如果不按类型分组,我该怎么做?另外我没有更新权限,不能使用存储过程。我还必须记住,table1 是涉及多个内部连接的查询的结果,我不想一遍又一遍地用于选择语句。

【问题讨论】:

为什么| H | 25 | c2 | 行完全没有变化? | H | 15 | c1 || H | 15 | c3 | 也一样? @MatBailie,因为需要更新任何一个(H,Cs)组合,而不是更多 【参考方案1】:

看看这是否有意义。我添加了 ID 列只是为了以与输入相同的顺序显示最终结果(以便于阅读)。

SQL> -- T1 is what you currently have; it can/could be your current query
SQL> with t1 (id, cat, val, type) as
  2    (select 1, 'A', 100, 'C1' from dual union all
  3     select 2, 'H', 25 , 'C2' from dual union all
  4     select 3, 'H', 50 , 'C3' from dual union all
  5     select 4, 'H', 30 , 'C2' from dual union all
  6     select 5, 'A', 15 , 'C3' from dual union all
  7     select 6, 'H', 10 , 'C1' from dual union all
  8     select 7, 'H', 15 , 'C1' from dual union all
  9     select 8, 'B', 10 , 'C4' from dual union all
 10     select 9, 'H', 20 , 'C4' from dual union all
 11     select 10,'H', 15 , 'C3' from dual
 12    ),
 13  -- sum VAL per type
 14  t1_sum as
 15    (select type, sum(val) sum_val
 16     from t1
 17     group by type
 18    ),
 19  -- find row number; let any H be number 1
 20  t1_rn as
 21    (select id, cat, val, type,
 22       row_number() over (partition by type
 23                          order by case when cat = 'H' then 1 end) rn
 24     from t1
 25    )
 26  -- the final result; add SUM_VAL to the first H row per type
 27  select r.cat, r.val + case when r.rn = 1 then s.sum_val else 0 end val,
 28    r.type
 29  From t1_rn r join t1_sum s on s.type = r.type
 30  order by r.id;

CAT        VAL TYPE
--- ---------- ----
A          100 C1
H           80 C2
H          130 C3
H           30 C2
A           15 C3
H          135 C1
H           15 C1
B           10 C4
H           50 C4
H           15 C3

10 rows selected.

SQL>

[编辑:试图阐明如何使用您的大型查询]

假设这是您的非常大且复杂的查询:

select a.cat, 
       case when a.cat = 'A' then b.val 
            when a.cat = 'Z' then c.val
            else 'H'
       end val,
       c.type
from a join b on a.id = b.id and a.x = b.y
       join c on c.id = b.idx
where a.date_column < sysdate
  and c.type = 'X';

正如我所说,创建一个基于它的视图

create or replace view v_view as
select a.cat, 
       case when a.cat = 'A' then b.val 
            when a.cat = 'Z' then c.val
            else 'H'
       end val,
       c.type
from a join b on a.id = b.id and a.x = b.y
       join c on c.id = b.idx
where a.date_column < sysdate
  and c.type = 'X';

并将其用作“我的”查询的来源(从第 14 行开始):

with t1_sum as
  (select type, sum(val) sum_val
   from v_view                      --> here's the view
   group by type
  ), etc.

或者,使用“巨大”查询本身作为初始 CTE:

with t1 as
-- this is your "huge" query
(select a.cat,  
       case when a.cat = 'A' then b.val 
            when a.cat = 'Z' then c.val
            else 'H'
       end val,
       c.type
from a join b on a.id = b.id and a.x = b.y
       join c on c.id = b.idx
where a.date_column < sysdate
  and c.type = 'X'
),
-- sum VAL per type
t1_sum as
  (select type, sum(val) sum_val
   from t1
   group by type
  ), etc.

【讨论】:

但是如果table1中的记录数很高怎么办?在实际场景中,我的表中有大约 500 万条记录。我当然不能单独选择使用 ID 我也想只使用一次 t1,因为它有多个内部连接和大量的 case 语句,这使得多次使用时查询看起来非常麻烦。 您的“具有多个内部连接和大量案例语句的大型查询”将是我的 T1 CTE。如果您讨厌看到它,请根据该查询创建一个视图。谁说选择个人ID?如果您指的是“我的 ID”列,请再次阅读我所说的内容。最后,如果您编写自己的代码(或者等待更长时间或无限期地等待其他人发布另一个选项),我没有任何异议。很快:要么接受,要么离开。 肯定会“接受它”,只需进行一些澄清 - 1.我如何编写语句“select 1, 'A', 100, 'C1' from dual union all ...”我在表中的所有行和 2. 如果我使用复杂视图,我可以对其进行进一步分组吗?无论如何感谢您努力回答 我已经编辑了我的消息并添加了更多代码,希望能说明我的意思。请看一看。现在更有意义了吗?

以上是关于通过输入 sum(column) 值来更新记录的主要内容,如果未能解决你的问题,请参考以下文章

通过从另一个表中查找某个范围内的值来游标并更新数据库记录

sqlalchemy 更新column,如果存在则更新,如果不存在,则添加新记录

如果 Column_X 更新,PLSQL 触发器记录对审计表的更新

更新 SELECT 语句的结果

通过在 MYSQl 中更新其值来插入重复行

有道云Markdown输入数学公式(更新中……)