Используйте рекурсивное условие факторинга подзапроса и используйте INSTR
, чтобы итеративно найти разделители, а затем SUBSTR
, чтобы извлечь значения:
Oracle Настройка :
CREATE TABLE results ( echo, type, color, active ) AS
SELECT 'echo1', 'car', 'yellow,green,blue', 'no,no,no' FROM DUAL UNION ALL
SELECT 'echo1', 'car', 'yellow,green', 'yes,yes' FROM DUAL UNION ALL
SELECT 'echo2', 'car', 'green,blue,red', 'no,no,no' FROM DUAL UNION ALL
SELECT 'echo2', 'car', 'blue,red', 'yes,yes' FROM DUAL UNION ALL
SELECT 'echo3', 'car', 'yellow,green', 'no,yes' FROM DUAL;
Запрос :
WITH lines ( echo, type, rn, idx, color, active, c_start, c_end, a_start, a_end ) AS (
SELECT echo,
type,
ROW_NUMBER() OVER ( ORDER BY echo, type, color, active ),
1,
color,
active,
1,
INSTR(color,',',1),
1,
INSTR(active,',',1)
FROM results
UNION ALL
SELECT echo,
type,
rn,
idx + 1,
color,
active,
c_end + 1,
INSTR(color,',',c_end + 1),
a_end + 1,
INSTR(active,',',a_end + 1)
FROM lines
WHERE c_end > 0
AND a_end > 0
)
SELECT echo,
type,
CASE c_end
WHEN 0
THEN SUBSTR( color, c_start )
ELSE SUBSTR( color, c_start, c_end - c_start )
END AS color,
CASE a_end
WHEN 0
THEN SUBSTR( active, a_start )
ELSE SUBSTR( active, a_start, a_end - a_start )
END AS active
FROM lines
ORDER BY rn, idx
Вывод :
ECHO | TYPE | COLOR | ACTIVE
:---- | :--- | :----- | :-----
echo1 | car | yellow | yes
echo1 | car | green | yes
echo1 | car | yellow | no
echo1 | car | green | no
echo1 | car | blue | no
echo2 | car | blue | yes
echo2 | car | red | yes
echo2 | car | green | no
echo2 | car | blue | no
echo2 | car | red | no
echo3 | car | yellow | no
echo3 | car | green | yes
db <> fiddle здесь
Update
Не объединять, а затем разбивать строки с разделителями; просто извлеките значения из XML:
CREATE TABLE table_name ( xml_field ) AS
SELECT XMLTYPE( '<rowCollection>
<row>
<column name="active">YES</column>
<column name="customertype">Default</column>
<column name="type">Default</column>
<column name="risklevel">Default</column>
<column name="color">yellow</column>
</row>
<row>
<column name="active">YES</column>
<column name="customertype">Default</column>
<column name="type">Default</column>
<column name="risklevel">Default</column>
<column name="color">green</column>
</row>
</rowCollection>' ) FROM DUAL;
Запрос :
SELECT x.*
FROM table_name t
CROSS JOIN
XMLTABLE(
'/rowCollection/row'
PASSING t.xml_field
COLUMNS
active VARCHAR2(3) PATH '/row/column[@name="active"]',
type VARCHAR2(10) PATH '/row/column[@name="type"]',
color VARCHAR2(10) PATH '/row/column[@name="color"]'
) x;
Выход :
Будет способ сгенерировать столбец echo
; но это не входит в ваши данные.
ACTIVE | TYPE | COLOR
:----- | :------ | :-----
YES | Default | yellow
YES | Default | green
db <> fiddle здесь