如果我正确理解这一点,您需要获取逗号分隔内的所有值对组合(1,1),(2,2)等不同的值对。
第一步是将字符串转换为行并选择一个rownumber以及值 -
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)}
。为了消除重复并以您想要的方式检索行 - 请确保第二个表的rownumber大于第一个。这样你会得到 - {(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;
简单来说什么我想要的是在listagg中获取案例,然后将该列表结果转换为行。因此,如果listagg包含(abc; def)将其转换为Col_1 = abc column2 = def – Mohamed
预期的结果看起来不合逻辑。问题不明确。 –
改变这个问题也许它会有道理。 – Mohamed