Db2
將逗號分隔的條目拆分為行
我有一張這樣的桌子:
| ID | OtherID | Data +--------+-----------+--------------------------- | 5059 | 73831 | 5103,5107 | 5059 | 73941 | 5103,5104,5107 | 5059 | 73974 | 5103,5106,5107,5108
結果應該返回單獨的行,如下所示:
| ID | OtherID | Data +--------+-----------+-------------------------- | 5059 | 73831 | 5103 | 5059 | 73831 | 5107 | 5059 | 73941 | 5103 | 5059 | 73941 | 5104 | 5059 | 73941 | 5107 | 5059 | 73974 | 5103 | 5059 | 73974 | 5106 | 5059 | 73974 | 5107 | 5059 | 73974 | 5108
基本上,我需要將逗號處的數據拆分為單獨的行。
結果將儲存在臨時表中(如:)
ID, OtherID, NewID
。我的 DB2 版本是 9.7
我根據我正在做的一些工作以及對Serge Rielau 和 Rick Swagerman 在 IBM developerWorks 上發布的解決方案的一些修改,為您的數據集提出了一個解決方案。
數據設置查詢:
DECLARE GLOBAL TEMPORARY TABLE sample_data (id INTEGER, otherid integer, data VARCHAR(255)) WITH REPLACE ON COMMIT preserve rows NOT logged; INSERT INTO session.sample_data SELECT 5059, 73831, '5103,5107' FROM sysibm.sysdummy1; INSERT INTO session.sample_data SELECT 5059, 73941, '5103,5104,5107' FROM sysibm.sysdummy1; INSERT INTO session.sample_data SELECT 5059, 73974, '5103,5106,5107,5108' FROM sysibm.sysdummy1;
解決方案選擇查詢:
WITH split_data AS ( SELECT id as group_by_1, otherid as group_by_2, data AS split_string, ',' AS split FROM session.sample_data ) , rec ( group_by_1, group_by_2, split_string, split, row_num, column_value, pos ) AS ( SELECT group_by_1, group_by_2, split_string, split, 1, VARCHAR(SUBSTR(split_string, 1, DECODE(INSTR(split_string, split, 1), 0, LENGTH(split_string), INSTR(split_string, split, 1) - 1)), 255), INSTR(split_string, split, 1) + LENGTH(split) FROM split_data UNION ALL SELECT group_by_1, group_by_2, split_string, split, row_num + 1, VARCHAR(SUBSTR(split_string, pos, DECODE(INSTR(split_string, split, pos), 0, LENGTH(split_string) - pos + 1, INSTR(split_string, split, pos) - pos)), 255), INSTR(split_string, split, pos) + LENGTH(split) FROM rec WHERE row_num < 30000 AND pos > LENGTH(split) ) SELECT group_by_1 as id, group_by_2 as otherid, column_value AS data FROM rec ORDER BY group_by_1, group_by_2, row_num;
結果:
ID OTHERID DATA 5059 73831 5103 5059 73831 5107 5059 73941 5103 5059 73941 5104 5059 73941 5107 5059 73974 5103 5059 73974 5106 5059 73974 5107 5059 73974 5108
註釋:
通過在 REC 表定義中包含盡可能多的 GROUP_BY_X 行(O 到多個)並在兩個聯合子選擇中匹配行,可以修改解決方案選擇查詢以滿足您的特定結果需求。
聚會有點晚了,但我最近有一個項目,我需要用更簡單的解決方案完成類似的事情,並認為我應該使用 XMLTABLE 而不是遞歸 SQL 來分享這種方法。
數據設置
數據設置與 Jeff Rudnick 的回答相同。
DECLARE GLOBAL TEMPORARY TABLE session.sample_data ( ID INTEGER, OtherId INTEGER, Data VARCHAR(255) ) WITH REPLACE ON COMMIT PRESERVE ROWS NOT LOGGED; INSERT INTO session.sample_data values (5059, 73831, '5103,5107'), (5059, 73941, '5103,5104,5107'), (5059, 73974, '5103,5106,5107,5108');
解決方案
SELECT sd.ID, sd.OtherId, si.item as NewId from session.sample_data sd ,XMLTABLE('$doc/items/item' PASSING XMLPARSE(DOCUMENT CAST('<items><item><value>'||replace(sd.Data,',','</value></item><item><value>')||'</value></item></items>' as CLOB)) as "doc" COLUMNS ITEM VARCHAR(255) PATH 'value' ) si ;
結果
ID OTHERID NEWID 5059 73831 5103 5059 73831 5107 5059 73941 5103 5059 73941 5104 5059 73941 5107 5059 73974 5103 5059 73974 5106 5059 73974 5107 5059 73974 5108