如果字符串包含数字模式,则提取

问题描述 投票:0回答:3

我在数据集中有一个列,我要在其中提取特定位置的数字仅IF字符串的结构包含#-#-#

我将如何用SQL编写(当前在雪花中编写)?

示例:

Column_A
abc-net-met-1234-12345-431-5968
abc-eme-ejt-emdn-1948-192
jen-mdk-ent-193-102-1029398
loe-ekd-12-49-nfm

我希望我的预期输出是:

Column_A                            Number1    Number2    Number3   Number4
abc-net-met-1234-12345-431-5968        1234      12345        431      5968
abc-eme-ejt-emdn-1948-192              NULL       NULL       NULL      NULL            
jen-mdk-ent-193-102-1029398             193        102    1029398      NULL
loe-ekd-12-49-nfm                      NULL       NULL       NULL      NULL

我认为可能是这样,但是有麻烦:

CASE WHEN COLUMN_A LIKE '%#-#-#%' THEN SPLIT_PART(COLUMN_A, '-', 4) ELSE NULL END Number1
CASE WHEN COLUMN_A LIKE '%#-#-#%' THEN SPLIT_PART(COLUMN_A, '-', 5) ELSE NULL END Number2
CASE WHEN COLUMN_A LIKE '%#-#-#%' THEN SPLIT_PART(COLUMN_A, '-', 6) ELSE NULL END Number3
CASE WHEN COLUMN_A LIKE '%#-#-#%' THEN SPLIT_PART(COLUMN_A, '-', 7) ELSE NULL END Number4
sql split sql-like snowflake-datawarehouse
3个回答
1
投票

我认为您的like表达式太宽泛。您可以使用正则表达式匹配来缩小它,例如:

CASE 
    WHEN COLUMN_A RLIKE '.*(^|-)[0-9]+-[0-9]+-[0-9]+($|-).*' 
    THEN SPLIT_PART(COLUMN_A, '-', 4) 
    ELSE NULL 
END Number1

[正则表达式在3个连续的数字组上匹配,这些数字组之间用破折号隔开,并以破折号开头(或位于字符串的开头),或后接破折号(或位于字符串的结尾)。


0
投票

我没有手头的雪花,但是类似的东西应该可以工作:这是建议的方法:将字符串拆分为一个表,枚举数字,然后使用条件聚合。

我没有雪花可以测试,但是像这样:

select column_a,
       max(case when seqnum = 1 then value end) as number_1,
       max(case when seqnum = 2 then value end) as number_2,
       max(case when seqnum = 3 then value end) as number_3,
       max(case when seqnum = 4 then value end) as number_4
from (select t.column_a, s.*,
             row_number() over (partition by (case when s.value rlike '^[0-9]+$'
                                                   then 1 else 0
                                              end)
                                              order by s.index
                               ) as seqnum
      from t cross join lateral
           split_to_table(t.column_a, '-') s
     ) t
group by column_a;

0
投票

我不确定为什么将当前的“正确答案”标记为这样,因为尽管它选择了正确的行,但是它并没有以任何特别有用的方式拆分结果。

以下查询通过首先匹配至少具有3个连续数字的行来提取正确答案,然后从3个数字的子字符串中提取第n个数字:

WITH TEST_TAB AS (SELECT * FROM (VALUES
    ('abc-net-met-1234-12345-431-5968'),
    ('abc-eme-ejt-emdn-1948-192'),
    ('jen-mdk-ent-193-102-1029398'),
    ('loe-ekd-12-49-nfm')
  ) T(COLUMN_A))
SELECT
  REGEXP_SUBSTR(REGEXP_SUBSTR('-'||COLUMN_A||'-', '(-[0-9]+){3,}-'), '[0-9]+', 1, 1) Num1,
  REGEXP_SUBSTR(REGEXP_SUBSTR('-'||COLUMN_A||'-', '(-[0-9]+){3,}-'), '[0-9]+', 1, 2) Num2,
  REGEXP_SUBSTR(REGEXP_SUBSTR('-'||COLUMN_A||'-', '(-[0-9]+){3,}-'), '[0-9]+', 1, 3) Num3,
  REGEXP_SUBSTR(REGEXP_SUBSTR('-'||COLUMN_A||'-', '(-[0-9]+){3,}-'), '[0-9]+', 1, 4) Num4
FROM TEST_TAB;
© www.soinside.com 2019 - 2024. All rights reserved.