2016-08-31 2 views
1

Есть ли способ в SQL разбить строку на n столбцов на основе разделителя в строке. Я знаю функцию SPLIT_PART, где есть три аргумента: строка, разделитель и n-й разделитель в строке. Пример:Vertica SQL Функция, используемая для разделения строки на отдельные столбцы

select 
    split_part('2016-01-01 00:11:00|Sprout|0', '|', 1), split_part('2016-01-01 00:11:00|Sprout|0', '|', 2), split_part('2016-01-01 00:11:00|Sprout|0', '|', 3); 

Есть ли способ сделать это без третьего аргумента, где бы вы просто поставить строку и разделитель, и вы бы в конечном итоге с, однако многие колоннах разделителем появляется в строке?

Как только Vertica разрешает UDF на основе Python, я знаю, что это простое исправление с использованием метода .split(), но есть ли решение в настоящее время? Я знаю, что это, вероятно, длинный выстрел, но я в основном прошу из любопытства, поскольку использование split_part отлично работает для моих целей.

Это не возможно было бы приемлемым ответом

ответ

1

Ok. Если вы счастливы, чтобы просто получить п-й маркер строки, попробуйте:

SQL>SELECT 
    ...> regexp_substr(
    ...> '2016-01-01 00:11:00|Sprout|0' -- source string 
    ...> , '[|]?([^|]+)' -- pattern (an optional bar, followed by many non-bars, which we remember as the 1st group) 
    ...> , 1    -- starting from begin of string: position 1 
    ...> , 1    -- the N-th occurrence 
    ...> , ''   -- no regexp modifier 
    ...> , 1    -- we want the only remembered group - the 1st 
    ...> ) the_first 
    ...>, regexp_substr(
    ...> '2016-01-01 00:11:00|Sprout|0' -- source string 
    ...> , '[|]?([^|]+)' -- pattern (an optional bar, followed by many non-bars, which we remember as the 1st group) 
    ...> , 1    -- starting from begin of string: position 1 
    ...> , 2    -- the N-th occurrence 
    ...> , ''   -- no regexp modifier 
    ...> , 1    -- we want the only remembered group - the 1st 
    ...> ) the_second 
    ...>, regexp_substr(
    ...> '2016-01-01 00:11:00|Sprout|0' -- source string 
    ...> , '[|]?([^|]+)' -- pattern (an optional bar, followed by many non-bars, which we remember as the 1st group) 
    ...> , 1    -- starting from begin of string: position 1 
    ...> , 3    -- the N-th occurrence 
    ...> , ''   -- no regexp modifier 
    ...> , 1    -- we want the only remembered group - the 1st 
    ...> ) the_third 
    ...>; 
    the_first     |the_second     |the_third 
    2016-01-01 00:11:00   |Sprout      |0 

Но если вы хотите, чтобы повернуть вашу строку с разделителями, так что каждый маркер формирует новую линию - две возможности:

SQL>-- manual, using regexp_substr ... 
    ...>with 
    ...>the_array as (
    ...>   select 1 as idx 
    ...>union all select 2 
    ...>union all select 3 
    ...>union all select 4 
    ...>union all select 5 
    ...>union all select 6 
    ...>union all select 7 
    ...>union all select 8 
    ...>union all select 9 
    ...>union all select 10 -- increase if you might get a bigger array than one of 10 elements 
    ...>) 
    ...> ,concepts as (
    ...>select '2016-01-01 00:11:00|Sprout|0' as concepts_list 
    ...>) 
    ...>select * from (
    ...> select 
    ...> idx 
    ...> ,trim(
    ...> regexp_substr(
    ...>  concepts_list -- source string 
    ...> ,'[|]?([^|]+)' -- pattern (an optional bar, followed by many non-bars, which we remember as the 1st group) 
    ...> ,1    -- starting from begin of string: position 1 
    ...> ,idx   -- the idx-th occurrence 
    ...> ,''   -- no regexp modifier 
    ...> ,1    -- we want the only remembered group - the 1st 
    ...> ) 
    ...> ) as concept 
    ...> from concepts 
    ...> cross join the_array 
    ...>) foo 
    ...>where concept <> '' 
    ...>; 
    idx     |concept 
         1|2016-01-01 00:11:00 
         3|0 
         2|Sprout 
    select succeeded; 3 rows fetched 
    SQL>-- using the strings_package on: 
    ...>-- https://github.com/vertica/Vertica-Extension-Packages/blob/master/strings_package/src/StringTokenizerDelim.cpp 
    ...>WITH csvtab(id,delimstring) AS (
    ...>   SELECT 1,'2016-01-01 00:11:00|Sprout|0' 
    ...>UNION ALL SELECT 2,'2016-01-02 00:11:00|Trout|1' 
    ...>UNION ALL SELECT 3,'2016-01-03 00:11:00|Salmon|2' 
    ...>UNION ALL SELECT 4,'2016-01-04 00:11:00|Bass|3' 
    ...>) 
    ...>SELECT id, words 
    ...>FROM (
    ...> SELECT id, v_txtindex.StringTokenizerDelim(delimstring,'|') OVER (PARTITION by id) FROM csvtab 
    ...>) a 
    ...>ORDER BY 1; 
    id     |words 
         1|2016-01-01 00:11:00 
         1|Sprout 
         1|0 
         2|2016-01-02 00:11:00 
         2|Trout 
         2|1 
         3|2016-01-03 00:11:00 
         3|Salmon 
         3|2 
         4|2016-01-04 00:11:00 
         4|Bass 
         4|3 
    select succeeded; 12 rows fetched 
+0

Мне было интересно, могу ли я получить отдельные столбцы, не имея 3 элементов в инструкции select. Если вы знакомы с Python, мне нужен эффект string.split ('|'). Полностью штраф, если это невозможно в SQL. Ваш первый пример - это маршрут, который я, вероятно, собираюсь использовать с помощью функции vertica SPLIT_PART (строка, разделитель, появление). – mangodreamz

Смежные вопросы