繁体   English   中英

Teradata:基于分隔符解析字符串,然后返回在解析字符串中找到的不同值

[英]Teradata: Parsing a string based on a delimiter, then returning distinct values found in parsed string

我有一个现有的数据库,其中包含一个我们可以调用“PACKAGES”的列,其中的值连接起来形成一个字符串,每一行还包含一个相应的“ACCOUNT_ID”值。

Row 1: ACCOUNT_ID = 123, PACKAGES = 'AAA BBB CCC '
Row 2: ACCOUNT_ID = 456, PACKAGES = ' DDD DDD AAA BBB CCC CCC EEE'
Row 3: ACCOUNT_ID = 789, PACKAGES = 'FFF ZZZ QQQ QQQ'

我需要生成代码,让我为每个帐户分隔包字段,以便 1) 代码识别何时空格引导字符,如第 2 行中的字符,以及 2) 仅显示各个帐户的不同包,即使 ACCOUNT_ID 字段是'在结果答案集中没有区别。

ACCOUNT_ID | PACKAGES    
123        | AAA
123        | BBB
123        | CCC
456        | DDD
456        | AAA
456        | BBB
456        | CCC
456        | EEE
789        | FFF
789        | ZZZ
789        | QQQ

我尝试在下面在线找到的一些示例代码中使用REGEXP ,但我不知道在哪里可以从我正在使用的数据库中输入表名,也不知道是否可以替换我的“PACKAGES”字段使用下面的任何代码来获得我需要的东西。

SELECT * FROM TABLE (

    REGEXP_SPLIT_TO_TABLE ('SMART PHONES','MOTOROLA&MICROSOFT&GOOGLE&APPLE','&','C')

    RETURNS (OUTKEY VARCHAR(10), TOKEN_NDX INTEGER, TOKEN VARCHAR(10))

) AS T1;

regexp_split_to_table 的语法总是让我抓狂。

select
*
from
table (regexp_split_to_table(<your db.table>.account_id,<your db.table>.packages, ' ','c')
returns   (account_Id integer, tok_num integer,package varchar(100))) as t

这会给你:

account_Id  tok_num package
    123     1       AAA
    123     2       BBB
    123     3       CCC

要仅获得不同的值,您可以运行:

select
 distinct account_id,package
from
table (regexp_split_to_table(<your db.table>.account_id,<your db.table>.packages, ' ','c')
returns   (account_Id integer, tok_num integer,package varchar(100))) as t
order by account_id,package

编辑:

在您对超出长度的评论之后,我做了一点挖掘。 STRTOK_SPLIT_TO_STRING 似乎能够处理更长的字符串,包括比 REGEXP_SPLIT_TO_STRING 更长的字符串(不要问我为什么......)。 所以,从@DNoeth 挖一点,这里有一些东西可以尝试:

with cte as (
select account_id,
cast(packages as clob)
from your_table)
SELECT
  DISTINCT account_Id, package
FROM TABLE (StrTok_Split_To_Table(cte.account_id,cte.packages, ' ')
     RETURNS (account_Id INTEGER, tok_num INTEGER,package VARCHAR(100))) AS t

我拼凑了一个巨大的(60k)字符串并用它测试了这个逻辑,它对我有用。 请注意,需要强制转换为 clob,否则您将收到相同的错误。

添加到@Andrew'sanswer。

将数据传递给表运算符的最简单方法是使用通用表表达式:

WITH cte AS
 ( -- whatever you need to prepare your data
   SELECT * FROM your_table 
 )
SELECT
  DISTINCT account_Id, package
FROM TABLE (RegExp_Split_To_Table(cte.account_id,cte.packages, ' ','c')
     RETURNS (account_Id INTEGER, tok_num INTEGER,package VARCHAR(100))) AS t

但是在您的情况下,不需要 RegEx,还有另一个 UDF 可以根据分隔符拆分字符串:

WITH cte AS
 ( -- whatever you need to prepare your data
   SELECT * FROM your_table 
 )
SELECT
  DISTINCT account_Id, package
FROM TABLE (StrTok_Split_To_Table(cte.account_id,cte.packages, ' ')
     RETURNS (account_Id INTEGER, tok_num INTEGER,package VARCHAR(100))) AS t

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM