更新不同数据类型的单列
Update single column of different data types
我在 Oracle 数据库中有三个 table:
内容,CONTENT_DATA,DATA_TYPE
CONTENT_DATA中的数据记录如下:
PK_ID DATA_TYPE_ID CONTENT_ID VALUE
1 1 1 0
2 2 1 100
3 3 1 200
我需要根据 CONTENT_DATA table 中的 DATA_TYPE_ID 将 'value' 列更新为其他 'value' 列的总和,这个过程应该是为每个 CONTENT_ID 完成。
例如:VALUE(DATA_TYPE(3)) = SUM(VALUE(DATA_TYPE(1)), VALUE(DATA_TYPE(2)))
我创建了如下所示的程序。但是它运行得很慢。有没有更好的选择来处理这样的问题?
CREATE OR REPLACE PROCEDURE UPDATE_DATA
AS
CURSOR your_cursor is
SELECT DISTINCT CONTENT_ID FROM CONTENT_DATA;
item your_cursor%rowtype;
BEGIN
OPEN your_cursor;
loop
FETCH your_cursor INTO item;
UPDATE CONTENT_DATA SET VALUE =
(SELECT SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN(1,2)
AND CONTENT_ID = item.CONTENT_ID)
WHERE CONTENT_ID = item.CONTENT_ID AND DATA_TYPE_ID = 3;
UPDATE CONTENT_DATA SET VALUE = (SELECT SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN(3,4,5,6,7,8,9)
AND CONTENT_ID = item.CONTENT_ID)
WHERE CONTENT_ID = item.CONTENT_ID
AND DATA_TYPE_ID = 10;
UPDATE CONTENT_DATA SET VALUE = (SELECT SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN( 10,11,12,13,14)
AND CONTENT_ID = item.CONTENT_ID)
WHERE CONTENT_ID = item.CONTENT_ID
AND DATA_TYPE_ID = 15;
end loop;
close your_cursor;
END;
我认为您不需要为此使用游标。我为您构建了一个测试用例以查看它的行为方式,然后您只需更改三个游标中的三个更新语句即可,而无需使用游标
测试用例
SQL> create table my_merge_test ( pk_id number, data_type_id number, content_id number, value number );
SQL> select * from my_merge_test ;
PK_ID DATA_TYPE_ID CONTENT_ID VALUE
---------- ------------ ---------- ----------
1 1 1 0
2 2 1 100
3 3 1 200
4 3 1 120
5 3 1 120
现在,让我们看看你想在第一次更新时做什么:
UPDATE CONTENT_DATA SET VALUE =
(SELECT SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN(1,2)
AND CONTENT_ID = item.CONTENT_ID)
WHERE CONTENT_ID = item.CONTENT_ID AND DATA_TYPE_ID = 3;
对于数据类型为 1 或 2 的每个 content_id,当项目相同且数据类型为3.其他的更新逻辑是一样的,只是值不同
不使用游标,您可以使用 with 子句在一个语句中执行操作
SQL> update my_merge_test t
2 set t.value = (
3 with source as ( select content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN(1,2)
group by content_id
)
select h.sum_value
from source h
where h.content_id = t.content_id and t.data_type_id = 3
) where t.data_type_id = 3
; 4 5 6 7 8 9 10
3 rows updated.
SQL> select * from my_merge_test ;
PK_ID DATA_TYPE_ID CONTENT_ID VALUE
---------- ------------ ---------- ----------
1 1 1 0
2 2 1 100
3 3 1 100
4 3 1 100
5 3 1 100
SQL>
那么第二次更新就是
update my_merge_test t
set t.value = (
with source as ( select content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN (3,4,5,6,7,8,9)
group by content_id
)
select h.sum_value
from source h
where h.content_id = t.content_id and t.data_type_id = 10
) where t.data_type_id = 10
;
第三个是
update my_merge_test t
set t.value = (
with source as ( select content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN ( 10,11,12,13,14)
group by content_id
)
select h.sum_value
from source h
where h.content_id = t.content_id and t.data_type_id = 15
) where t.data_type_id = 15
;
用您的表格替换名称,让我知道它是否满足您的需要。
我在 Oracle 数据库中有三个 table: 内容,CONTENT_DATA,DATA_TYPE
CONTENT_DATA中的数据记录如下:
PK_ID DATA_TYPE_ID CONTENT_ID VALUE
1 1 1 0
2 2 1 100
3 3 1 200
我需要根据 CONTENT_DATA table 中的 DATA_TYPE_ID 将 'value' 列更新为其他 'value' 列的总和,这个过程应该是为每个 CONTENT_ID 完成。 例如:VALUE(DATA_TYPE(3)) = SUM(VALUE(DATA_TYPE(1)), VALUE(DATA_TYPE(2)))
我创建了如下所示的程序。但是它运行得很慢。有没有更好的选择来处理这样的问题?
CREATE OR REPLACE PROCEDURE UPDATE_DATA
AS
CURSOR your_cursor is
SELECT DISTINCT CONTENT_ID FROM CONTENT_DATA;
item your_cursor%rowtype;
BEGIN
OPEN your_cursor;
loop
FETCH your_cursor INTO item;
UPDATE CONTENT_DATA SET VALUE =
(SELECT SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN(1,2)
AND CONTENT_ID = item.CONTENT_ID)
WHERE CONTENT_ID = item.CONTENT_ID AND DATA_TYPE_ID = 3;
UPDATE CONTENT_DATA SET VALUE = (SELECT SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN(3,4,5,6,7,8,9)
AND CONTENT_ID = item.CONTENT_ID)
WHERE CONTENT_ID = item.CONTENT_ID
AND DATA_TYPE_ID = 10;
UPDATE CONTENT_DATA SET VALUE = (SELECT SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN( 10,11,12,13,14)
AND CONTENT_ID = item.CONTENT_ID)
WHERE CONTENT_ID = item.CONTENT_ID
AND DATA_TYPE_ID = 15;
end loop;
close your_cursor;
END;
我认为您不需要为此使用游标。我为您构建了一个测试用例以查看它的行为方式,然后您只需更改三个游标中的三个更新语句即可,而无需使用游标
测试用例
SQL> create table my_merge_test ( pk_id number, data_type_id number, content_id number, value number );
SQL> select * from my_merge_test ;
PK_ID DATA_TYPE_ID CONTENT_ID VALUE
---------- ------------ ---------- ----------
1 1 1 0
2 2 1 100
3 3 1 200
4 3 1 120
5 3 1 120
现在,让我们看看你想在第一次更新时做什么:
UPDATE CONTENT_DATA SET VALUE =
(SELECT SUM(NVL(VALUE,0)) FROM CONTENT_DATA WHERE DATA_TYPE_ID IN(1,2)
AND CONTENT_ID = item.CONTENT_ID)
WHERE CONTENT_ID = item.CONTENT_ID AND DATA_TYPE_ID = 3;
对于数据类型为 1 或 2 的每个 content_id,当项目相同且数据类型为3.其他的更新逻辑是一样的,只是值不同
不使用游标,您可以使用 with 子句在一个语句中执行操作
SQL> update my_merge_test t
2 set t.value = (
3 with source as ( select content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN(1,2)
group by content_id
)
select h.sum_value
from source h
where h.content_id = t.content_id and t.data_type_id = 3
) where t.data_type_id = 3
; 4 5 6 7 8 9 10
3 rows updated.
SQL> select * from my_merge_test ;
PK_ID DATA_TYPE_ID CONTENT_ID VALUE
---------- ------------ ---------- ----------
1 1 1 0
2 2 1 100
3 3 1 100
4 3 1 100
5 3 1 100
SQL>
那么第二次更新就是
update my_merge_test t
set t.value = (
with source as ( select content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN (3,4,5,6,7,8,9)
group by content_id
)
select h.sum_value
from source h
where h.content_id = t.content_id and t.data_type_id = 10
) where t.data_type_id = 10
;
第三个是
update my_merge_test t
set t.value = (
with source as ( select content_id, SUM(NVL(value,0)) as sum_value from my_merge_test where DATA_TYPE_ID IN ( 10,11,12,13,14)
group by content_id
)
select h.sum_value
from source h
where h.content_id = t.content_id and t.data_type_id = 15
) where t.data_type_id = 15
;
用您的表格替换名称,让我知道它是否满足您的需要。