我有一个现有的数据库,其中包含一列,我们可以将其称为“ 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)代码在SPACE领先于第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;
答案 0 :(得分:1)
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
编辑:
在您对超出长度的评论之后,我做了一些深入探讨。与REGEXP_SPLIT_TO_STRING相比,STRTOK_SPLIT_TO_STRING似乎能够处理更长的字符串,包括Clob(不要问我为什么...)。因此,从@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,否则会出现相同的错误。
答案 1 :(得分:1)
添加到@Andrew的答案中。
将数据传递给表运算符的最简单方法是使用通用表表达式:
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