针对特定场景将 Select Oracle 查询转换为更新
Convert Select Oracle Query To Updte for specific scenario
我们正在使用 Oracle v12+
我们有这样一种情况,我们需要将 status
列更新为以前的值 每当我们有第一个 RENEWAL
时每个 code
(它是功能 ID,并且针对一个 ID 有很多行)否则 ADD
.
请参阅下面的示例 i/o。数据按每个 ID 的时间戳排序。
我们需要特定的连接来更新吗?为此,我已将数据复制到临时 table,但没有成功。
Table 姓名:table_book_status
Input CLOB
[code] [word] [status] [timestamp]
B000JMLBHU book {"name" : "Kunal", "type" : "RENEWAL"}
B000JMLBHU read {"name" : "Kunal", "type" : "RENEWAL"}
B000JMLBHU was {"name" : "Kunal", "type" : "MODIFY"}
B000JMLBHU story {"name" : "Kunal", "type" : "ADD"}
B000R93D4Y with {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y book {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y story {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y was {"name" : "RAHUL", "type" : "MODIFY"}
B000R93D4Y have {"name" : "RAHUL", "type" : "ADD"}
B001892DGG was {"name" : "Kanav", "type" : "ADD"}
B001892DWA was {"name" : "Kavita", "type" : "ADD"}
B001BXNQ2O was {"name" : "Keshav", "type" : "RENEWAL"}
B001BXNQ2O book {"name" : "Keshav", "type" : "RENEWAL"}
B001H55R8M was {"name" : "Raghav", "type" : "MODIFY"}
B001HQHCBQ was {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ story {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ bella {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ with {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ love {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ zsadist {"name" : "RINA", "type" : "ADD"}
Output
[code] [word] [status] [timestamp]
B000JMLBHU book {"name" : "Kunal", "type" : "RENEWAL"}
B000JMLBHU read {"name" : "Kunal", "type" : "**MODIFY**"}
B000JMLBHU was {"name" : "Kunal", "type" : "MODIFY"}
B000JMLBHU story {"name" : "Kunal", "type" : "ADD"}
B000R93D4Y with {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y book {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y story {"name" : "RAHUL", "type" : "**MODIFY**"}
B000R93D4Y was {"name" : "RAHUL", "type" : "MODIFY"}
B000R93D4Y have {"name" : "RAHUL", "type" : "ADD"}
B001892DGG was {"name" : "Kanav", "type" : "ADD"}
B001892DWA was {"name" : "Kavita", "type" : "ADD"}
B001BXNQ2O was {"name" : "Keshav", "type" : "RENEWAL"}
B001BXNQ2O book {"name" : "Keshav", "type" : "**ADD**"}
B001H55R8M was {"name" : "Raghav", "type" : "MODIFY"}
B001HQHCBQ was {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ story {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ bella {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ with {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ love {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ zsadist {"name" : "RINA", "type" : "ADD"}
在 Whosebug 社区的帮助下,我们能够创建 select 查询
SELECT code,
status,
CASE
WHEN sm = 1
AND status = 'RENEWAL'
THEN COALESCE(lgst, 'ADD')
ELSE status
END AS status1,
timestamp
FROM
(SELECT code,
JSON_VALUE(status, '$.type') AS status,
SUM(
CASE
WHEN JSON_VALUE(status, '$.type') = 'RENEWAL'
THEN 1
ELSE 0
END) over (partition BY code order by timestamp) AS sm,
lag(JSON_VALUE(status, '$.type')) over (partition BY code order by timestamp) AS lgst,
timestamp
FROM table_book_status
);
这会根据需要给出完美的结果,但在 select 视图中,我们希望将其转换为 UPDATE
oracle 查询或 PL/SQL
。对此有何建议。
从查询更新 table 的一种好方法是使用 MERGE 语句。这是一个复制 all_objects 并添加一列与该行所有者和类型匹配的对象数的示例。
CREATE TABLE all_objects_2 AS
SELECT *
FROM all_objects;
ALTER TABLE all_objects_2 add owner_and_type_ct NUMBER;
MERGE INTO all_objects_2 ao2
USING (SELECT ao.owner,
ao.object_type,
COUNT(*) AS ct
FROM all_objects ao
GROUP BY ao.owner,
ao.object_type) x
ON (ao2.owner = x.owner AND ao2.object_type = x.object_type)
WHEN MATCHED THEN
UPDATE
SET ao2.owner_and_type_ct = x.ct;
SELECT ao2.owner,
ao2.object_name,
ao2.object_type,
ao2.owner_and_type_ct
FROM all_objects_2 ao2
WHERE rownum < 10;
/*
SYS C_TS# CLUSTER 10
SYS I_TS# INDEX 1459
SYS C_FILE#_BLOCK# CLUSTER 10
SYS I_FILE#_BLOCK# INDEX 1459
SYS FET$ TABLE 1592
SYS UET$ TABLE 1592
SYS SEG$ TABLE 1592
SYS UNDO$ TABLE 1592
SYS TS$ TABLE 1592
*/
你 MERGE INTO [destination table] USING [your query] ON [criteria to join query to destination] 并且当你匹配一行时,你用查询中的值更新该行。您还可以使用 MERGE 进行 INSERT 和 DELETE,但我不会复制所有 documentation.
我们正在使用 Oracle v12+
我们有这样一种情况,我们需要将 status
列更新为以前的值 每当我们有第一个 RENEWAL
时每个 code
(它是功能 ID,并且针对一个 ID 有很多行)否则 ADD
.
请参阅下面的示例 i/o。数据按每个 ID 的时间戳排序。
我们需要特定的连接来更新吗?为此,我已将数据复制到临时 table,但没有成功。
Table 姓名:table_book_status
Input CLOB
[code] [word] [status] [timestamp]
B000JMLBHU book {"name" : "Kunal", "type" : "RENEWAL"}
B000JMLBHU read {"name" : "Kunal", "type" : "RENEWAL"}
B000JMLBHU was {"name" : "Kunal", "type" : "MODIFY"}
B000JMLBHU story {"name" : "Kunal", "type" : "ADD"}
B000R93D4Y with {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y book {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y story {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y was {"name" : "RAHUL", "type" : "MODIFY"}
B000R93D4Y have {"name" : "RAHUL", "type" : "ADD"}
B001892DGG was {"name" : "Kanav", "type" : "ADD"}
B001892DWA was {"name" : "Kavita", "type" : "ADD"}
B001BXNQ2O was {"name" : "Keshav", "type" : "RENEWAL"}
B001BXNQ2O book {"name" : "Keshav", "type" : "RENEWAL"}
B001H55R8M was {"name" : "Raghav", "type" : "MODIFY"}
B001HQHCBQ was {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ story {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ bella {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ with {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ love {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ zsadist {"name" : "RINA", "type" : "ADD"}
Output
[code] [word] [status] [timestamp]
B000JMLBHU book {"name" : "Kunal", "type" : "RENEWAL"}
B000JMLBHU read {"name" : "Kunal", "type" : "**MODIFY**"}
B000JMLBHU was {"name" : "Kunal", "type" : "MODIFY"}
B000JMLBHU story {"name" : "Kunal", "type" : "ADD"}
B000R93D4Y with {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y book {"name" : "RAHUL", "type" : "RENEWAL"}
B000R93D4Y story {"name" : "RAHUL", "type" : "**MODIFY**"}
B000R93D4Y was {"name" : "RAHUL", "type" : "MODIFY"}
B000R93D4Y have {"name" : "RAHUL", "type" : "ADD"}
B001892DGG was {"name" : "Kanav", "type" : "ADD"}
B001892DWA was {"name" : "Kavita", "type" : "ADD"}
B001BXNQ2O was {"name" : "Keshav", "type" : "RENEWAL"}
B001BXNQ2O book {"name" : "Keshav", "type" : "**ADD**"}
B001H55R8M was {"name" : "Raghav", "type" : "MODIFY"}
B001HQHCBQ was {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ story {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ bella {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ with {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ love {"name" : "RINA", "type" : "ADD"}
B001HQHCBQ zsadist {"name" : "RINA", "type" : "ADD"}
在 Whosebug 社区的帮助下,我们能够创建 select 查询
SELECT code,
status,
CASE
WHEN sm = 1
AND status = 'RENEWAL'
THEN COALESCE(lgst, 'ADD')
ELSE status
END AS status1,
timestamp
FROM
(SELECT code,
JSON_VALUE(status, '$.type') AS status,
SUM(
CASE
WHEN JSON_VALUE(status, '$.type') = 'RENEWAL'
THEN 1
ELSE 0
END) over (partition BY code order by timestamp) AS sm,
lag(JSON_VALUE(status, '$.type')) over (partition BY code order by timestamp) AS lgst,
timestamp
FROM table_book_status
);
这会根据需要给出完美的结果,但在 select 视图中,我们希望将其转换为 UPDATE
oracle 查询或 PL/SQL
。对此有何建议。
从查询更新 table 的一种好方法是使用 MERGE 语句。这是一个复制 all_objects 并添加一列与该行所有者和类型匹配的对象数的示例。
CREATE TABLE all_objects_2 AS
SELECT *
FROM all_objects;
ALTER TABLE all_objects_2 add owner_and_type_ct NUMBER;
MERGE INTO all_objects_2 ao2
USING (SELECT ao.owner,
ao.object_type,
COUNT(*) AS ct
FROM all_objects ao
GROUP BY ao.owner,
ao.object_type) x
ON (ao2.owner = x.owner AND ao2.object_type = x.object_type)
WHEN MATCHED THEN
UPDATE
SET ao2.owner_and_type_ct = x.ct;
SELECT ao2.owner,
ao2.object_name,
ao2.object_type,
ao2.owner_and_type_ct
FROM all_objects_2 ao2
WHERE rownum < 10;
/*
SYS C_TS# CLUSTER 10
SYS I_TS# INDEX 1459
SYS C_FILE#_BLOCK# CLUSTER 10
SYS I_FILE#_BLOCK# INDEX 1459
SYS FET$ TABLE 1592
SYS UET$ TABLE 1592
SYS SEG$ TABLE 1592
SYS UNDO$ TABLE 1592
SYS TS$ TABLE 1592
*/
你 MERGE INTO [destination table] USING [your query] ON [criteria to join query to destination] 并且当你匹配一行时,你用查询中的值更新该行。您还可以使用 MERGE 进行 INSERT 和 DELETE,但我不会复制所有 documentation.