如何在列中找到非重复值,忽略特殊字符?

时间:2017-08-09 19:20:37

标签: sql database oracle

我有一个与我的作品相关的标签属性字段。我正在寻找这个领域的重复;问题是,输入是不一致的。例如:

Group  |  Label  |
---------------
1      |  H7     |
1      |  H-7    |
2      |  C9     |
2      |  C 9    |
3      |  D5     |
3      |  M 9    |

我正在寻找的结果只是:

3      |  D5     |
3      |  M 9    |

因为它们彼此真的不同。我目前使用以下查询:

SELECT *
FROM TABLE t3
WHERE t3.group IN (
  SELECT t1.group
  FROM TABLE t1, TABLE t2
  WHERE t1.group = t2.group
  AND (t1.label <> t2.label) 

如何让查询忽略特殊字符?

3 个答案:

答案 0 :(得分:2)

如果“特殊”字符可以是字母数字字符以外的任何字符,那么您可以使用regexp_replace

select max(t.group), max(t.label)
from your_table t
group by regexp_replace(t.label, '[^[:alnum:]]', '')
having count(*) = 1;

如果值中可能只有有限数量的特殊字符,则可能使用非“正则表达式”解决方案 - 使用replace

另外,请避免使用“group”等关键字作为标识符。

答案 1 :(得分:2)

尝试:

select regexp_replace(label,'[^[:alnum:]]',''), count(1) cnt
from some_table
group by regexp_replace(label,'[^[:alnum:]]','')
having count(1) > 1

这将显示重复的标签(仅基于字母数字)

答案 2 :(得分:1)

您可以使用regexp_replace()

SELECT t.*
FROM TABLE t
WHERE NOT EXISTS (SELECT 1
                  FROM TABLE tt
                  WHERE tt.group = t.group AND tt.rowid <> t.rowid AND
                        regexp_replace(tt.label, '[^a-zA-Z0-9]', '') = regexp_replace(t.label, '[^a-zA-Z0-9]', '')
                 );

这应该返回作为单例的所有原始行。如果你想要一个所有都是单身的组的所有行:

SELECT t.*
FROM TABLE t
WHERE t.group IN (SELECT tt.group
                  FROM (SELECT tt.group, regexp_replace(tt.label, '[^a-zA-Z0-9]', '') as label_clean, COUNT(*) as cnt
                        FROM TABLE tt
                        GROUP BY tt.group, regexp_replace(tt.label, '[^a-zA-Z0-9]', '')
                       ) tt
                   GROUP BY tt.group
                   HAVING MAX(cnt) = 1
                  );