针对特定场景将 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.