2016-08-31 2 views
1

문자열에 구분 기호에 따라 문자열을 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가 Python 기반 UDF를 허용하면 .split() 메소드를 사용하여 쉽게 수정할 수 있지만 현재 해결책이 있습니까? 나는 이것이 길다는 것을 알고 있지만 split_part를 사용하는 것이 내 목적을 위해 완벽하게 작동한다는 점을 호기심으로 묻고있다.

하면이 가능한 것은 허용되는 원치

답변

1

괜찮을 것 없다. 당신은 단지 문자열의 n 번째 토큰을 얻을 행복 경우, 시도 :

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

select 문에 3 개의 항목이 없어도 별도의 열을 얻을 수 있는지 궁금합니다. 파이썬에 익숙하다면, string.split ('|')의 효과를 원할 것입니다. 이것이 SQL에서 가능하지 않다면 완전히 괜찮습니다. 당신의 첫번째 예제는 vertica 함수 SPLIT_PART (string, delimiter, occurence)를 사용하여가는 길입니다. – mangodreamz

관련 문제