我在数据集中有一个列,我要在其中提取特定位置的数字仅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
我认为您的like
表达式太宽泛。您可以使用正则表达式匹配来缩小它,例如:
CASE
WHEN COLUMN_A RLIKE '.*(^|-)[0-9]+-[0-9]+-[0-9]+($|-).*'
THEN SPLIT_PART(COLUMN_A, '-', 4)
ELSE NULL
END Number1
[正则表达式在3个连续的数字组上匹配,这些数字组之间用破折号隔开,并以破折号开头(或位于字符串的开头),或后接破折号(或位于字符串的结尾)。
我没有手头的雪花,但是类似的东西应该可以工作:这是建议的方法:将字符串拆分为一个表,枚举数字,然后使用条件聚合。
我没有雪花可以测试,但是像这样:
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;
我不确定为什么将当前的“正确答案”标记为这样,因为尽管它选择了正确的行,但是它并没有以任何特别有用的方式拆分结果。
以下查询通过首先匹配至少具有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;