我在一个单元格中有一列具有重复值的列,请告诉我如何仅使用sql或pl / sql删除重复值。
| Test
-+--------------------------------------------------------------------
| 999999999(10145) 999999999(10145) 999999999(10145) 999999999(10145)
|--------------------------------------------------------------------
| 113307425(2) 310122174(2) 310122174(2) 113307425(2)
答案 0 :(得分:2)
使用带有反向引用的正则表达式来匹配重复项:
Oracle设置:
CREATE TABLE test_data ( value ) AS
SELECT '9999999(12345) 9999999(12345) 9999999(12345) 9999999(12345)' FROM DUAL;
查询:
SELECT REGEXP_REPLACE( value, '([^ ]+)( \1)+', '\1' ) AS replaced_value
FROM test_data
输出:
| REPLACED_VALUE | | :------------- | | 9999999(12345) |
db <>提琴here
已更新:对于第六次编辑中的新数据:
CREATE TABLE test_data ( value ) AS
SELECT '9999999(12345) 9999999(12345) 9999999(12345) 9999999(12345)' FROM DUAL UNION ALL
SELECT '113307425(2) 310122174(2) 310122174(2) 113307425(2)' FROM DUAL;
查询:
使用递归子查询分解子句在字符串中查找术语,然后使用DISTINCT
删除重复项,并使用LISTAGG
将它们重新组合成单个字符串。
WITH bounds ( id, value, start_pos, end_pos ) AS (
SELECT ROWID,
value,
1,
INSTR( value, ' ', 1 )
FROM test_data
UNION ALL
SELECT id,
value,
end_pos + 1,
INSTR( value, ' ', end_pos + 1 )
FROM bounds
WHERE end_pos > 0
),
strings ( id, value ) AS (
SELECT DISTINCT
id,
CASE end_pos
WHEN 0
THEN SUBSTR( value, start_pos )
ELSE SUBSTR( value, start_pos, end_pos - start_pos )
END
FROM bounds
)
SELECT LISTAGG( value, ' ' ) WITHIN GROUP ( ORDER BY value ) AS unique_values
FROM strings
GROUP BY id
输出:
| UNIQUE_VALUES | | :------------------------ | | 9999999(12345) | | 113307425(2) 310122174(2) |
db <>提琴here
答案 1 :(得分:0)
Oracle允许使用递归子查询因式分解,从而可以反复应用基于正则表达式的替换:
CREATE TABLE test_data ( value ) AS
SELECT '9999999(12345) 9999999(12345) 9999999(12345) 9999999(12345)' FROM DUAL;
WITH rep(n,s,n_maxrep) AS (
SELECT 1
, value
, 1 + LENGTH(REGEXP_REPLACE(value, '[^ ]', ''))
FROM test_data
UNION ALL
SELECT n+1
, REGEXP_REPLACE ( s, '([^ ]+)(( [^ ]+)*)( \1)+', '\1\2' )
, n_maxrep
FROM rep
WHERE n <= n_maxrep
)
SELECT s FROM rep WHERE n = n_maxrep;
说明
该查询反复对单个动词重复项应用相同的基于正则表达式的基本替换。到原始列。在这种情况下,“动词”是连续的非空格字符的最大序列。重复项可以彼此相邻或被其他动词分隔。
此类替换的最大可能数目是预先已知的:n-1
用于n
动词,当所有动词都相同时。这等于原始值中出现分隔符的次数。
其他所有都是语法糖。 Oracle自己构建嵌套的子查询链。
请注意,限制n_maxrep
实际上是1 + <分隔符出现次数>。这是必需的,因为基本情况(n=1
不能替代。