如何在Oracle中的选择中重申某个语句

发布于 2025-01-17 15:00:59 字数 1578 浏览 0 评论 0原文

有一个文本列,其中包含 JSON 表达式。根本不清楚 JSON 数组有多长,在下面的示例代码中,我重复了该短语最多六次(可能重复超过六次)。如何根据最长的数组长度重复重复(情况)? 我还想用变量 d_i 和 a_i 指定列名(这里 i 是计数器)。 我可以使用 while 或循环吗?如果是,怎么办? 注意:如果在任何行中,JSON 表达式中的第一个值不大于 0,则该行中 JSON 数组的长度为零,并且这种情况一直持续到表示末尾。这意味着,如果 JSON 数组的第一个单元格有值,则第二个单元格可能有值,如果第二个单元格没有值,则数组的长度肯定为 1。 如果发生这种情况,循环必须重新开始。 我希望我已经正确表达了我的意思。

select t.tx_id,
    --00
      case WHEN t.fee[0]:amount>0 then  t.fee[0]:denom end as d_0,
      case when t.fee[0]:amount>0 then t.fee[0]:amount/1000000 end as a_0,
    --01
     case WHEN t.fee[1]:amount>0 then  t.fee[1]:denom end as d_1,
      case when t.fee[1]:amount>0 then t.fee[1]:amount/1000000 end as a_1,
    --02
     case WHEN t.fee[2]:amount>0 then  t.fee[2]:denom end as d_2,
      case when t.fee[2]:amount>0 then t.fee[2]:amount/1000000 end as a_2,
    --03
     case WHEN t.fee[3]:amount>0 then  t.fee[3]:denom end as d_3,
      case when t.fee[3]:amount>0 then t.fee[3]:amount/1000000 end as a_3,
    --04
     case WHEN t.fee[4]:amount>0 then  t.fee[4]:denom end as d_4,
      case when t.fee[4]:amount>0 then t.fee[4]:amount/1000000 end as a_4,
    --05
     case WHEN t.fee[5]:amount>0 then  t.fee[5]:denom end as d_5,
      case when t.fee[5]:amount>0 then t.fee[5]:amount/1000000 end as a_5,
    --06
     case WHEN t.fee[6]:amount>0 then  t.fee[6]:denom end as d_6,
      case when t.fee[6]:amount>0 then t.fee[6]:amount/1000000 end as a_6

from terra.transactions t 
    where t.tx_id not in (select s.tx_id from terra.swaps s)   and fee[0].amount>0 limit 1000

There is a column of text with JSON expressions in it. It is not at all clear how long the JSON array is, and in the example code below I have repeated the phrase up to six times (it can be more than six repetitions). How can I repeat a duplicate (case when) based on the longest array length?
I also want to specify the column names with the variables d_i and a_i (here i is the counter).
Can I use a while or loop? If Yes, HOW?
Note: If in any row, the first value in the JSON expression is not greater than 0, then the length of the JSON array in that row is zero, and this continues until the end of the representation. This means that if the first cell of the JSON array has a value, the second cell may have a value, and if the second cell has no value, then the length of the array is definitely 1.
If this condition occurs, the loop must start again.
I hope I have stated what I mean correctly.

select t.tx_id,
    --00
      case WHEN t.fee[0]:amount>0 then  t.fee[0]:denom end as d_0,
      case when t.fee[0]:amount>0 then t.fee[0]:amount/1000000 end as a_0,
    --01
     case WHEN t.fee[1]:amount>0 then  t.fee[1]:denom end as d_1,
      case when t.fee[1]:amount>0 then t.fee[1]:amount/1000000 end as a_1,
    --02
     case WHEN t.fee[2]:amount>0 then  t.fee[2]:denom end as d_2,
      case when t.fee[2]:amount>0 then t.fee[2]:amount/1000000 end as a_2,
    --03
     case WHEN t.fee[3]:amount>0 then  t.fee[3]:denom end as d_3,
      case when t.fee[3]:amount>0 then t.fee[3]:amount/1000000 end as a_3,
    --04
     case WHEN t.fee[4]:amount>0 then  t.fee[4]:denom end as d_4,
      case when t.fee[4]:amount>0 then t.fee[4]:amount/1000000 end as a_4,
    --05
     case WHEN t.fee[5]:amount>0 then  t.fee[5]:denom end as d_5,
      case when t.fee[5]:amount>0 then t.fee[5]:amount/1000000 end as a_5,
    --06
     case WHEN t.fee[6]:amount>0 then  t.fee[6]:denom end as d_6,
      case when t.fee[6]:amount>0 then t.fee[6]:amount/1000000 end as a_6

from terra.transactions t 
    where t.tx_id not in (select s.tx_id from terra.swaps s)   and fee[0].amount>0 limit 1000

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合约呢 2025-01-24 15:00:59

假设您有表:

CREATE TABLE transactions (
  tx_id NUMBER PRIMARY KEY,
  fee   JSON
);

使用数据:

INSERT INTO transactions (tx_id, fee) VALUES (
  1,
  '[{"denom":"ABC","amount":100},{"denom":"DEF","amount":0},{"denom":"GHI","amount":1}]'
);

最简单的方法是将数据输出为行(而不是作为列):

select t.tx_id,
       j.*
from   terra.transactions t
       CROSS JOIN JSON_TABLE(
         t.fee,
         '$[*]'
         COLUMNS
           denom  VARCHAR2(20) PATH '$.denom',
           amount NUMBER       PATH '$.amount'
       ) j
where  t.tx_id not in (select s.tx_id from terra.swaps s)
and    j.amount>0

哪个输出:

tx_iddenom
1abc100
1ghi1

如果您想将行动态旋转到列,那么最好在任何中间层应用程序(PHP,C#,Java,Python等)中完成,以访问数据库。如果您想在Oracle中进行操作,则可以查看这个问题的答案 。

db<> fiddle

Assuming that you have the table:

CREATE TABLE transactions (
  tx_id NUMBER PRIMARY KEY,
  fee   JSON
);

With the data:

INSERT INTO transactions (tx_id, fee) VALUES (
  1,
  '[{"denom":"ABC","amount":100},{"denom":"DEF","amount":0},{"denom":"GHI","amount":1}]'
);

Then the simplest method is to output the data as rows (and not as columns):

select t.tx_id,
       j.*
from   terra.transactions t
       CROSS JOIN JSON_TABLE(
         t.fee,
         '$[*]'
         COLUMNS
           denom  VARCHAR2(20) PATH '$.denom',
           amount NUMBER       PATH '$.amount'
       ) j
where  t.tx_id not in (select s.tx_id from terra.swaps s)
and    j.amount>0

Which outputs:

TX_IDDENOMAMOUNT
1ABC100
1GHI1

If you want to dynamically pivot the rows to columns then this is best done in whatever middle-tier application (PHP, C#, Java, Python, etc.) that you are using to access the database. If you want to do it in Oracle then you can look at the answers to this question.

db<>fiddle here

子栖 2025-01-24 15:00:59

我使用展平表:

with flattenTable as (
SELECT
    tx_id,
    fee,
    b.value as fee_parsed,
    b.value:amount as fee_amount,
    b.value:denom as fee_denom
  FROM terra.transactions, TABLE(FLATTEN(terra.transactions.fee)) b 
  where tx_id not in (select s.tx_id from terra.swaps s ) and fee_amount>0)
  SELECT f.*,
  case when f.fee_denom='uusd' then f.fee_amount/1000000 else f.fee_amount/1000000*(select 
              avg(price_usd) 
            from terra.oracle_prices o,flattenTable f
            where o.CURRENCY = f.fee_denom  and o.block_timestamp=CURRENT_DATE) end as Fee_USD
  from flattenTable f
  limit 100

I use flatten table:

with flattenTable as (
SELECT
    tx_id,
    fee,
    b.value as fee_parsed,
    b.value:amount as fee_amount,
    b.value:denom as fee_denom
  FROM terra.transactions, TABLE(FLATTEN(terra.transactions.fee)) b 
  where tx_id not in (select s.tx_id from terra.swaps s ) and fee_amount>0)
  SELECT f.*,
  case when f.fee_denom='uusd' then f.fee_amount/1000000 else f.fee_amount/1000000*(select 
              avg(price_usd) 
            from terra.oracle_prices o,flattenTable f
            where o.CURRENCY = f.fee_denom  and o.block_timestamp=CURRENT_DATE) end as Fee_USD
  from flattenTable f
  limit 100
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文