2014-04-11 24 views
3

我在下表的Teradata 14,我不允許寫程序和函數自己,但我可以用strtokstrtok_split_to_table如何在Teradata 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,但得到了一個錯誤A column or character expression is larger than max size

另外我想strtok_split_to_table,並能建立一個修改後的表,但不如何從

回答

2

爲什麼您將非規範化數據存儲在RDBMS中,然後對其進行處理以創建更差的非規格化輸出?

從鏈接修改我的解決方案張貼到利用,而不是遞歸STRTOK_SPLIT_TO_TABLE:

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; 

如果你有訪問TDStats.udfconcat功能,它可以進一步簡化(但有辦法控制的順序性質:

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)=' '; 
相關問題