Teradata: анализ строки на основе разделителя, а затем возвращение различных значений, найденных в разобранной строке - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть существующая база данных, содержащая столбец, который мы можем назвать «ПАКЕТАМИ» со значениями, объединенными для создания строки, каждая строка также содержит соответствующее значение «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 в некотором примере кода, который я нашел в Интернете ниже, но я не знаю, где я могу ввести имя таблицы из базы данных, которую я использую,и я не знаю, смогу ли я заменить свое поле "ПАКЕТЫ" любым из приведенных ниже кодов, чтобы получить то, что мне нужно.

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;

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

Добавление к @ 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
1 голос
/ 25 сентября 2019

Синтаксис для 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

Я собрал огромную (60 КБ) строку и проверил эту логику с ней, это сработало для меня.Обратите внимание, что приведение к clob обязательно, иначе вы получите ту же ошибку.

...