2014-04-11 4 views
3

나는 에서 다음 표 테라 데이타 14, 나는 프로 시저를 작성할 수와 자신을 기능,하지만 난 strtok, strtok_split_to_tableTeradata 14에서 하위 문자열을 그룹화하는 방법은 무엇입니까?

id property 
1 1234X (Yel), 2225Y (Red), 1234X (Gre), 
2 
3 1222Y (Pin), 
4 1134E (Yel), 4565Y (Whi), 1134E (Red), 2222Y (Red), 

를 사용하고 있지 않다 않은 내가 어떻게 그룹 위의 표 있도록 각 개체 하나의 괄호

id property 
1 1234X (Yel Gre), 2225Y (Red), 
2 
3 1222Y (Pin), 
4 1134E (Yel Red), 4565Y (Whi), 2222Y (Red), 

속성 코드에있는 모든 속성을 가질 것입니다 항상 5 문자열, 예를 들면이다 1222Y. 색상 코드는 항상 3 자입니다 (예 : Pin


나는 this solution를 사용하여 시도하지만 strtok_split_to_table를 시도 또한 오류 A column or character expression is larger than max size

를 가지고와 수정 된 테이블을 생성 할 수 있었다, 그러나이 시도하는

답변

2

왜 비정규 화 된 데이터를 RDBMS에 저장 한 다음이를 처리하여 더욱 비정규 화 된 출력을 생성합니까? 링크에서 내 솔루션을 수정

대신 재귀의 STRTOK_SPLIT_TO_TABLE를 활용 게시 : 당신이 TDStats.udfconcat 기능에 대한 액세스 권한을 가지고있는 경우

SELECT 
    id, 
    MAX(CASE WHEN newpos = 1 AND newgrp <> '(),' THEN newgrp ELSE '' END) || 
    MAX(CASE WHEN newpos = 2 THEN newgrp ELSE '' END) || 
    MAX(CASE WHEN newpos = 3 THEN newgrp ELSE '' END) || 
    MAX(CASE WHEN newpos = 4 THEN newgrp ELSE '' END) || 
    MAX(CASE WHEN newpos = 5 THEN newgrp ELSE '' END) || 
    MAX(CASE WHEN newpos = 6 THEN newgrp ELSE '' END) 
    -- add as many CASEs as needed 
FROM 
( 
    SELECT 
    id, 
    ROW_NUMBER() 
    OVER (PARTITION BY id 
      ORDER BY newgrp) AS newpos, 
    TRIM(a || ' (' || 
    MAX(CASE WHEN tokennum = 1 THEN b || ' ' ELSE '' END) || 
    MAX(CASE WHEN tokennum = 2 THEN b || ' ' ELSE '' END) || 
    MAX(CASE WHEN tokennum = 3 THEN b || ' ' ELSE '' END) || 
    MAX(CASE WHEN tokennum = 4 THEN b || ' ' ELSE '' END) || 
    MAX(CASE WHEN tokennum = 5 THEN b || ' ' ELSE '' END) || 
    MAX(CASE WHEN tokennum = 6 THEN b || ' ' ELSE '' END) 
    -- add as many CASEs as needd 
    ) || '), ' AS newgrp 
    FROM 
    (
     SELECT 
     id, tokennum, 
     TRIM(SUBSTRING(token FROM 1 FOR POSITION('(' IN TRIM(token)||'(') - 1)) AS a, 
     TRIM(TRAILING ')' FROM SUBSTRING(token FROM POSITION('(' IN token) + 1)) AS b 
     FROM 
     TABLE(STRTOK_SPLIT_TO_TABLE(vt.id, vt.property, ',') 
     RETURNS (id INT, 
       tokennum INT, 
       token VARCHAR(30) CHARACTER SET UNICODE 
       ) 
      ) AS dt 
    ) AS dt 
    GROUP BY id, a 
) AS dt 
GROUP BY id; 

이 더 간단하게 할 수 있습니다 (그러나의 순서를 제어하는 ​​방법이 특성 :.

대부분의 작업이 요청 된 출력을 얻을 수있는 적절한 장소에서 공백과 쉼표로 조롱했다
SELECT id, 
    CASE 
    WHEN TRIM(TDStats.udfconcat(' ' || a || ' ' || b)) || ',' <> '(),' 
    THEN TRIM(TDStats.udfconcat(' ' || a || ' ' || b)) || ',' 
    ELSE '' 
    END 
FROM 
(
    SELECT 
    id, 
    TRIM(SUBSTRING(token FROM 1 FOR POSITION('(' IN TRIM(token)||'(') - 1)) AS a, 
    '('|| OTRANSLATE(TDStats.udfconcat(TRIM(TRAILING ')' FROM SUBSTRING(token FROM POSITION('(' IN token) + 1))), ',', ' ') || ')'AS b 
    FROM 
    TABLE(STRTOK_SPLIT_TO_TABLE(vt.id, vt.property, ',') 
    RETURNS (id INT, 
       tokennum INT, 
       token VARCHAR(30) CHARACTER SET UNICODE 
      ) 
     ) AS dt 
    GROUP BY id, a 
) AS dt 
GROUP BY id; 

아직도 RDBMS에 데이터를 저장하지 않습니다.

2

에서 진행하지 않는 방법 , 귀하의 게시물에서 dnoeths 쿼리를 약간 수정했습니다.

WITH RECURSIVE cte 
(id, 
    len, 
remaining, 
word, 
pos 
) AS (
SELECT 
id, 
POSITION(',' IN property || ',') - 1 AS len, 
SUBSTRING(property || ',' FROM len + 2) AS remaining, 
TRIM(SUBSTRING(property FROM 1 FOR len)) AS word, 
1 
FROM TableA 
UNION ALL 
SELECT 
id, 
POSITION(',' IN remaining)- 1 AS len_new, 
SUBSTRING(remaining FROM len_new + 2), 
TRIM(SUBSTRING(remaining FROM 1 FOR len_new)), 
pos + 1 
FROM cte 
WHERE remaining <> '' 
) 
SELECT 
id, 
MAX(CASE WHEN newpos = 1 THEN newgrp ELSE '' END) || 
MAX(CASE WHEN newpos = 2 THEN newgrp ELSE '' END) || 
MAX(CASE WHEN newpos = 3 THEN newgrp ELSE '' END) || 
MAX(CASE WHEN newpos = 4 THEN newgrp ELSE '' END) || 
MAX(CASE WHEN newpos = 5 THEN newgrp ELSE '' END) || 
MAX(CASE WHEN newpos = 6 THEN newgrp ELSE '' END) 
-- add as many CASEs as needed 
FROM 
( 
    SELECT 
id, 
ROW_NUMBER() 
OVER (PARTITION BY id 
     ORDER BY newgrp) AS newpos, 
a || 
MAX(CASE WHEN pos = 1 THEN '(' || b ELSE '' END) || 
MAX(CASE WHEN pos = 2 THEN ' ' || b ELSE '' END) || 
MAX(CASE WHEN pos = 3 THEN ' ' || b ELSE '' END) || 
MAX(CASE WHEN pos = 4 THEN ' ' || b ELSE '' END) || 
MAX(CASE WHEN pos = 5 THEN ' ' || b ELSE '' END) || 
MAX(CASE WHEN pos = 6 THEN ' ' || b ELSE '' END) 
-- add as many CASEs as needed 
|| '), ' AS newgrp 
FROM 
(
    SELECT 
    id, 
    ROW_NUMBER() 
    OVER (PARTITION BY id, a 
      ORDER BY pos) AS pos, 
    SUBSTRING(word FROM 1 FOR POSITION('(' IN word) - 1) AS a, 
    TRIM(TRAILING ')' FROM SUBSTRING(word FROM POSITION('(' IN word) + 1)) AS b 
    FROM cte 
WHERE word <> '' 
) AS dt 
GROUP BY id, a 
) AS dt 
    GROUP BY id 
    UNION ALL 
    SELECT id,property FROM TableA WHERE property IS NULL OR TRIM(property)=' '; 
관련 문제