首页 > 解决方案 > 将 Select Oracle Query 转换为特定场景的 Updte

问题描述

我们正在使用Oracle v12+

我们有一种情况,我们需要将status 列更新为先前的值,只要我们有第RENEWAL一个code(它是功能 ID,并且针对一个 ID 有很多行),否则ADD

请参阅下面的示例 i/o。数据按每个 ID 的时间戳排序。

我们需要特定的连接来更新吗?为此,我已将数据复制到临时表中,但没有成功。

表名: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"}

在 stackOverflow 社区的帮助下,我们能够创建一个选择查询

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

这会根据需要提供完美的结果,但在选择视图中,我们希望将其转换为UPDATEoracle 查询或PL/SQL. 对此有任何建议。

标签: databaseoracleupdatesoracle12cinsert-update

解决方案


从查询更新表的一个好方法是使用 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,但我不会复制所有文档


推荐阅读