【问题标题】:Convert Select Oracle Query To Updte for specific scenario将选择 Oracle 查询转换为特定场景的更新
【发布时间】:2020-05-23 01:14:44
【问题描述】:

我们正在使用 Oracle v12+

我们有一种情况,我们需要更新status 列到以前的值,每当我们为每个code 拥有第一个RENEWAL 时(它是功能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
  );

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

【问题讨论】:

    标签: database oracle updates oracle12c insert-update


    【解决方案1】:

    从查询中更新表的一个好方法是使用 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

    【讨论】:

      猜你喜欢
      • 2014-01-05
      • 2017-05-06
      • 2019-01-18
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      • 2023-03-30
      • 2017-06-20
      • 1970-01-01
      相关资源
      最近更新 更多