我正在尝试分析以下与分层和正则表达式相关的查询,任何人都可以帮助我理解吗?

I am trying to analyze below query related to hierarchical and Regex can any one help me in understanding?

我遇到了以下查询,但我无法得出与以下查询相关的分析结论。以下查询的主要目的是将数字转换为字母。但是分层查询的用法让我很困惑。

merge into s_export ex
using (
       select
        listagg(n, '') within group (order by lv) new_val,
        row_id
      from
        (
          SELECT
            connect_by_root rowid row_id,
            LEVEL lv,
            CASE
               WHEN Regexp_like(Regexp_substr( file_as, '[^0-9]+|((\d+)(st|nd|rd|th)?)', 1, LEVEL ), '\d+')
                  THEN spell_number(
                                Regexp_substr( file_as, '[^0-9]+|((\d+)(st|nd|rd|th)?)', 1, LEVEL, NULL, 2),
                                Regexp_substr( file_as, '[^0-9]+|((\d+)(st|nd|rd|th)?)', 1, LEVEL, NULL, 3)
                               )
               ELSE Regexp_substr( file_as, '[^0-9]+|((\d+)(st|nd|rd|th)?)', 1, LEVEL )
            END N
          FROM s_export d
          CONNECT BY NOCYCLE Regexp_substr( file_as, '([^0-9]+)|(\d+)(st|nd|rd|th)?', 1, LEVEL ) IS NOT NULL
                             and rowid = prior rowid
                             and prior dbms_random.value is not null
        )
      group by row_id
                      ) t
on (t.row_id = ex.rowid)
when matched then
 update set ex.file_as = t.new_val;

示例数据集:

create table s_export  (file_as varchar2(2000));


insert into s_export  values ('Collection Four') ;
insert into s_export  values ('OM_Forty-One One');
insert into s_export  values ('OM_Twenty-Two | SOFifteen');
insert into s_export  values ('1st');
insert into s_export  values ('3M');
insert into s_export  values ('Collection Six');
insert into s_export  values ('2ND');
insert into s_export  values ('11TH100');

以下是我目前的理解:

  1. 我们正在对 table s_export 列执行更新 file_as 每当有任何数字说 1 时,它都会转换为 至 'one'.

  2. 至于 LEVELRegexp_substr 中的使用作为一个事件。

我已经分析了上面提到的查询,下面是我的分析以供参考。

考虑到我们的 table s_export 中有示例数据,我们的目标是 转换出现在字符串中的数值进入字母表.

file_as     ROW_ID
-------     -------
123Test123  101

我们可以将查询从最里面开始分成3部分

第 1 步:将字符串转换为字母表。

   SELECT
        connect_by_root rowid row_id,
        LEVEL lv,
        CASE
           WHEN Regexp_like(Regexp_substr( file_as, '[^0-9]+|((\d+)(st|nd|rd|th)?)', 1, LEVEL ), '\d+')
              THEN spell_number(
                            Regexp_substr( file_as, '[^0-9]+|((\d+)(st|nd|rd|th)?)', 1, LEVEL, NULL, 2),
                            Regexp_substr( file_as, '[^0-9]+|((\d+)(st|nd|rd|th)?)', 1, LEVEL, NULL, 3)
                           )
           ELSE Regexp_substr( file_as, '[^0-9]+|((\d+)(st|nd|rd|th)?)', 1, LEVEL )
        END N
      FROM s_export d
      CONNECT BY NOCYCLE Regexp_substr( file_as, '([^0-9]+)|(\d+)(st|nd|rd|th)?', 1, LEVEL ) IS NOT NULL
                         and rowid = prior rowid
                         and prior dbms_random.value is not null

如果 file_as 列中有任何字符串,在我们的例子中说“123Test123”,此查询将获取特定行的 row_id 并得到它们的子字符串例如将此字符串的 row_id 视为 101 现在将有 3 行具有相同的 row_id 唯一的区别是没有级别(没有拆分)并且每个数字都将被转换进入字母表,使用 (spell_number)

原值:123Test123

ROW_ID  LV      N
------- ------- -------
101     1       One Hundred Twenty-Three
101     2       Test
101     3       One Hundred Twenty-Three

2:对转换后的数据进行分组

 select
    listagg(n, '') within group (order by lv) new_val,
    row_id
  from (
  ---Query from Step 1
  )  group by row_id

现在从上面的输出中得到结果,我们将执行 "listagg"(比如将列旋转到行)并连接列 "N" 的值,从最内层的查询中得到基于对它们进行分组的单个字符串值 关于 row_id、

NEW_VAL                                                     ROW_ID
-------                                                     -------
One Hundred Twenty-Three Test One Hundred Twenty-Three      101

第三步:将数据合并到原来的列中table

merge into s_export ex
using (
        --Query from Step 2 (Including Step 1)
        )  t
on (t.row_id = ex.rowid)
when matched then
 update set ex.file_as = t.new_val;

现在,我们将在row_id.

的基础上,将上述查询得到的"NEW_VAL"合并到s_export的"file_as"列

最终转换结果:

file_as                                                     ROW_ID
-------                                                     -------
One Hundred Twenty-Three Test One Hundred Twenty-Three      101