Możesz to zrobić za pomocą rekurencyjnej klauzuli faktoryzacji podzapytania i prostych funkcji łańcuchowych (zamiast wolnych wyrażeń regularnych).
(Uwaga:nie ma to również problemów z hierarchicznymi zapytaniami, gdy istnieje wiele wierszy wejściowych, generujących wykładniczo więcej wierszy wyjściowych na każdej głębokości, ponieważ nie może skorelować każdego wiersza ze swoim rodzicem, więc skoreluje go ze wszystkimi wierszami na wcześniejszy poziom hierarchii).
Konfiguracja Oracle :
CREATE TABLE some_table( some_id, value ) AS
SELECT 8, 'A1,A2,A3;A4,A5,A6' FROM DUAL UNION ALL
SELECT 8, 'B1,B2,B3;B4,B5,B6' FROM DUAL UNION ALL
SELECT 8, 'C1,C2,C3;C4,C5,C6' FROM DUAL;
Zapytanie :
WITH line_start_end ( some_id, value, startidx, endidx ) AS (
SELECT some_id,
value,
1,
INSTR( value, ';', 1 )
FROM some_table
WHERE some_id = 8
UNION ALL
SELECT some_id,
value,
endidx + 1,
INSTR( value, ';', endidx + 1 )
FROM line_start_end
WHERE endidx > 0
)
SELECT some_id,
CASE
WHEN endidx = 0
THEN SUBSTR( value, startidx )
ELSE SUBSTR( value, startidx, endidx - startidx )
END AS value
FROM line_start_end;
Wyjście :
db<>fiddle tutaj