如果我理解正确,您需要在逗号分隔的字符串中获取所有值对组合,其中顺序不重要,不包括 (1,1)、(2,2) 等相同的值对。
第一步是将字符串转换为行并选择一个行号以及值 -
SELECT ROWNUM AS r,
REGEXP_SUBSTR (col_A,
'(.*?)(,|$)',
1,
LEVEL,
NULL,
1)
val
FROM my_table
CONNECT BY LEVEL <= REGEXP_COUNT (COL_A, ',') + 1;
然后与自身进行交叉连接。然而,这会给你同一对两次。所以像{(1,1), (1,2), (1,3), (2,1), (2,2), (2,3), (3,1), (3,2), (3,3)}。为了消除重复并以您想要的方式检索行 - 确保第二个表的行号大于第一个。这样你会得到 - {(1,2), (1,3), (2,3)}。
所以最终的查询看起来像 -
WITH my_table
AS (SELECT '1000016932,1000020056,1000020100,1000020144,1000020243'
AS col_A
FROM DUAL),
vals
AS ( SELECT ROWNUM AS r,
REGEXP_SUBSTR (col_A,
'(.*?)(,|$)',
1,
LEVEL,
NULL,
1)
val
FROM my_table
CONNECT BY LEVEL <= REGEXP_COUNT (COL_A, ',') + 1)
SELECT v_a.val AS col_B, v_B.val AS col_C
FROM vals v_A
CROSS JOIN vals v_B
WHERE v_B.val > v_A.val;
编辑:
因为可能有多行,所以最好使用某种 ID 列,使用它可以将行连接在一起。所以在这个例子中 -
ID COL_A
1 1,2,3,4
2 5,6,7
您唯一需要做的就是在拆分逗号分隔字符串时根据 ID 选择唯一行。
WITH my_table
AS (SELECT 1 AS id, '1,2,3,4' AS col_A FROM DUAL
UNION ALL
SELECT 2, '5,6,7' FROM DUAL),
vals
AS ( SELECT DISTINCT id,
REGEXP_SUBSTR (col_A,
'(.*?)(,|$)',
1,
LEVEL,
NULL,
1)
val
FROM my_table
CONNECT BY LEVEL <= REGEXP_COUNT (COL_A, ',') + 1)
SELECT v_a.val AS col_B, v_B.val AS col_C
FROM vals v_A
JOIN vals v_B ON v_A.id = v_B.id
WHERE v_B.val > v_A.val;
编辑 2:
我意识到我在比较实际值,这是不正确的。它会强制所有值都是整数。这是一个允许整数或字符串的查询。
WITH my_table
AS (SELECT 1 AS id, '1,2,3,4' AS col_A FROM DUAL
UNION ALL
SELECT 2, '5,6,7' FROM DUAL
UNION ALL
SELECT 3, 'a,b,c' FROM DUAL),
vals
AS ( SELECT DISTINCT id,
REGEXP_SUBSTR (col_A,
'(.*?)(,|$)',
1,
LEVEL,
NULL,
1)
val
FROM my_table
CONNECT BY LEVEL <= REGEXP_COUNT (COL_A, ',') + 1
ORDER BY id, val),
vals_r AS (SELECT ROWNUM AS r, vals.* FROM vals)
SELECT v_a.val AS col_B, v_B.val AS col_C
FROM vals_r v_A
JOIN vals_r v_B ON v_A.id = v_B.id
WHERE v_B.r > v_A.r;