这里有几个涉及递归子查询分解的替代方案:
WITH t1 AS (SELECT 1 id, 'PC1,PC2' col1, 'F1,F2' col2 FROM dual UNION ALL
SELECT 2 id, 'PC1,PC3,PC4' col1, 'F2,F3,F4' col2 FROM dual),
t2 AS (SELECT 'F1' col1, 'V1' col2 FROM dual UNION ALL
SELECT 'F2' col1, 'V2' col2 FROM dual UNION ALL
SELECT 'F3' col1, 'V3' col2 FROM dual UNION ALL
SELECT 'F4' col1, 'V4' col2 FROM dual),
-- end of mimicking your tables; see below for the rest of the query you'd need:
t1_rcrsv1 (ID, col1, split_col1, col2, lvl) AS (SELECT ID, col1, regexp_substr(col1,'[^,]+',1,1), col2, 1 lvl
FROM t1
UNION ALL
SELECT ID, col1, regexp_substr(col1,'[^,]+',1,lvl+1), col2, lvl + 1
FROM t1_rcrsv1
WHERE regexp_substr(col1,'[^,]+',1,lvl+1) IS NOT NULL),
t1_rcrsv2 (ID, col1, col2, split_col2, lvl) AS (SELECT ID, split_col1, col2, regexp_substr(col2,'[^,]+',1,1), 1 lvl
FROM t1_rcrsv1
UNION ALL
SELECT ID, col1, col2, regexp_substr(col2,'[^,]+',1,lvl+1), lvl + 1
FROM t1_rcrsv2
WHERE regexp_substr(col2,'[^,]+',1,lvl+1) IS NOT NULL)
SELECT t1a.id,
t1a.col1 t1_c1,
t1a.split_col2 t1_c2,
t2.col2 t2_c2
FROM t1_rcrsv2 t1a
INNER JOIN t2 ON t1a.split_col2 = t2.col1
ORDER BY t1a.ID, t1a.col1, t1a.split_col2;
ID T1_C1 T1_C2 T2_C2
---------- ----------- -------- -----
1 PC1 F1 V1
1 PC1 F2 V2
1 PC2 F1 V1
1 PC2 F2 V2
2 PC1 F2 V2
2 PC1 F3 V3
2 PC1 F4 V4
2 PC3 F2 V2
2 PC3 F3 V3
2 PC3 F4 V4
2 PC4 F2 V2
2 PC4 F3 V3
2 PC4 F4 V4
上面的查询首先循环通过col1,然后在加入第二个表之前循环通过col2。但是,您可能会发现在先循环 col2 之后,更早地进行连接会更快 - 如下所示:
WITH t1 AS (SELECT 1 id, 'PC1,PC2' col1, 'F1,F2' col2 FROM dual UNION ALL
SELECT 2 id, 'PC1,PC3,PC4' col1, 'F2,F3,F4' col2 FROM dual),
t2 AS (SELECT 'F1' col1, 'V1' col2 FROM dual UNION ALL
SELECT 'F2' col1, 'V2' col2 FROM dual UNION ALL
SELECT 'F3' col1, 'V3' col2 FROM dual UNION ALL
SELECT 'F4' col1, 'V4' col2 FROM dual),
-- end of mimicking your tables; see below for the rest of the query you'd need:
t1_rcrsv1 (ID, col1, col2, split_col2, lvl) AS (SELECT ID, col1, col2, regexp_substr(col2,'[^,]+',1,1), 1 lvl
FROM t1
UNION ALL
SELECT ID, col1, col2, regexp_substr(col2,'[^,]+',1,lvl+1), lvl + 1
FROM t1_rcrsv1
WHERE regexp_substr(col2,'[^,]+',1,lvl+1) IS NOT NULL),
t1_rcrsv2 (ID, col1, split_col1, col2, lvl, t2_c2) AS (SELECT t1a.ID, t1a.col1, regexp_substr(t1a.col1,'[^,]+',1,1), t1a.split_col2, 1 lvl, t2.col2
FROM t1_rcrsv1 t1a
INNER JOIN t2 ON t1a.split_col2 = t2.col1
UNION ALL
SELECT ID, col1, regexp_substr(col1,'[^,]+',1,lvl+1), col2, lvl + 1, t2_c2
FROM t1_rcrsv2
WHERE regexp_substr(col1,'[^,]+',1,lvl+1) IS NOT NULL)
SELECT id,
split_col1 t1_c1,
col2 t1_c2,
t2_c2
FROM t1_rcrsv2
ORDER BY ID, t1_c1, t1_c2;
ID T1_C1 T1_C2 T2_C2
---------- ----------- -------- -----
1 PC1 F1 V1
1 PC1 F2 V2
1 PC2 F1 V1
1 PC2 F2 V2
2 PC1 F2 V2
2 PC1 F3 V3
2 PC1 F4 V4
2 PC3 F2 V2
2 PC3 F3 V3
2 PC3 F4 V4
2 PC4 F2 V2
2 PC4 F3 V3
2 PC4 F4 V4
您需要测试这两个查询(以及 MT0 提供的解决方案),看看哪个最适合您。
注意如果要返回 table1 的所有拆分列,无论 table2 中是否存在匹配项,您可能需要将内连接转换为外连接。