DB2 SQL Как разбить столбец на потенциально много строк? - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть таблица с 2 полями (ID и профиль).

Таблица содержит много записей, но уникальна по идентификатору.
Профиль имеет длину 1000 символов, а каждые 10 символов - в основном это код профиля.
У некоторых идентификаторов может быть только 1 код, а у других их много.

Я не знаю, почему таблица была разработана таким образом.

Итак, запись может выглядеть примерно так:

ID              PROFILE
BOB             BM        BS        DM        FM        IC        IC6       IL        IM        JN101     MM        XC        XM        XR
BILL            ZZ        XY               

Есть ли способ разбить поле профиля, создавая новые строки

Так это будет выглядеть так:

ID              PROFILE
BOB             BM
BOB             BS
BOB             DM
...
BILL            ZZ
BILL            XY

I ' я действительно хотел бы иметь возможность создать представление каким-либо образом.

Ответы [ 2 ]

2 голосов
/ 24 февраля 2020

Попробуйте:

DB2 для LUW

/*
WITH TAB (ID, PROFILE) AS 
(
VALUES 
  ('BOB',  'BM        BS        DM        FM        IC        IC6       IL        IM        JN101     MM        XC        XM        XR')
, ('BILL', 'ZZ        XY')
)
*/
SELECT T.ID, V.TOK
FROM TAB T
, xmltable
(
'for $id in tokenize($s, " +") return <i>{string($id)}</i>' 
passing T.PROFILE as "s" 
columns 
  tok varchar(10) path '.'
) V;

Пример dbfiddle .

DB2 для LUW & IBM i

IBM i не поддерживает (по крайней мере, до 7.4) выражения FLWOR XQuery, поэтому вам нужно создать документ XML.

SELECT T.ID, V.TOK
FROM 
  TAB T
, XMLTABLE 
(
'$doc/d/i'
PASSING XMLPARSE(DOCUMENT '<d><i>' || regexp_replace(trim(T.PROFILE), '  +', '</i><i>') || '</i></d>') as "doc"
COLUMNS 
  TOK VARCHAR(10) PATH '.'
) V;
0 голосов
/ 25 февраля 2020

Пробовал с помощью split (). Кажется, очень медленно. Ниже показано 14,817 сек c.

WITH TAB (ID, PROFILE) AS 
(
VALUES 
  ('BOB',  cast('BM        BS        DM        FM        IC        IC6       IL        IM        JN101     MM        XC        XM        XR' as char(1000))), 
  ('BILL', cast('ZZ        XY' as char(1000)))
)
SELECT a.id, b.element as profile
from  tab a, 
      TABLE (systools.split(a.profile , ' ')) b
where b.element <> '';

По сравнению с ответом Иоахима, заняв всего 134 мс!

WITH TAB (ID, PROFILE) AS 
(
VALUES 
  ('BOB',  cast('BM        BS        DM        FM        IC        IC6       IL        IM        JN101     MM        XC        XM        XR' as char(1000))), 
  ('BILL', cast('ZZ        XY' as char(1000)))
)
SELECT a.id, b.item as PROFILE
  from tab a
      ,XMLTABLE('$doc/items/item'
          PASSING XMLPARSE(DOCUMENT CAST(   '<items><item>'
                                         || replace(a.profile , ' ' , '</item><item>')
                                         || '</item></items>' as CLOB
                                        )
                           ) as "doc"
          COLUMNS
          ITEM VARCHAR(255) PATH '.'
      ) b 
WHERE b.item <> '';
...