【问题标题】:I am trying to analyze below query related to hierarchical and Regex can any one help me in understanding?我正在尝试分析以下与分层和正则表达式相关的查询,任何人都可以帮助我理解吗?
【发布时间】:2018-10-12 22:39:28
【问题描述】:

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

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. 我们正在对表 s_export 列执行更新 file_as 只要有任何数字说1,它就会转换这个 到'one'。

  2. 就LEVEL 中使用的Regexp_substr 而言,作为一个事件发生。

【问题讨论】:

  • 从表s_export 中获取一些样本数据,然后您可以使用sqlfiddle.com dbfiddle.uk rextester.com/l/oracle_online_compiler 之类的服务来设置选择查询(不是更新)并研究结果。如果您仍然遇到问题,请将 URL 粘贴到示例中,以便我们提供帮助。没有样本数据 = 我们无能为力
  • @Used_By_Already 示例数据已更新,
  • 是的,我看到了示例数据,但我没有函数 spell_number()。我建议您只从 select ... to ... group by row_id 运行该查询的一部分并检查该结果
  • 是的,我已经执行了,但是很遗憾,该功能不起作用。

标签: sql oracle11g hierarchical listagg regexp-substr


【解决方案1】:

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

假设我们的表 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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 2021-08-29
    相关资源
    最近更新 更多