Oracle SQL:过滤包含非数字字符的行

Oracle SQL: Filtering rows with non-numeric characters

我的问题与此非常相似 one:删除 table 中包含 A 列和 B 列的所有行,其中一些记录包含非数字字符(看起来像 '1234#5 ' 或 '1bbbb')。但是,我阅读的解决方案似乎对我不起作用。例如,

SELECT count(*) FROM tbl  
--962060;


SELECT count(*)
FROM tbl
WHERE (REGEXP_like(A,'[^0-9]') OR REGEXP_like(B,'[^0-9]') ) ;
--17


SELECT count(*)
FROM tbl
WHERE (REGEXP_like(A,'[0-9]') and REGEXP_like(B,'[0-9]') )
;
--962060

在第三个查询中,我希望看到 (962060-17)=962043。为什么还是962060?像这样的 alternative 查询也给出相同的答案:

SELECT count(*)
FROM tbl
WHERE (REGEXP_like(A,'[[:digit:]]')and REGEXP_like(B,'[[:digit:]]') )
;
--962060

当然,我可以通过执行 query1 减去 query2 来绕过这个问题,但我想学习如何使用正则表达式来做到这一点。

如果您使用正则表达式,您应该考虑到字符串的任何部分都可能作为正则表达式进行匹配。根据您的示例,您应该指定整个字符串应仅包含数字 ^ - 是字符串的开头 $ - 是结尾。你可以使用 \d- 是数字

 SELECT count(*)
 FROM tbl
  WHERE (REGEXP_like(A,'^[0-9]+$') and REGEXP_like(B,'^[0-9]+$') )

 SELECT count(*)
 FROM tbl
  WHERE (REGEXP_like(A,'^\d+$') and REGEXP_like(B,'^\d+$') )

我知道您特别要求正则表达式解决方案,但 translate 也可以解决这类问题(而且通常速度更快,因为正则表达式使用更多处理能力):

select count(1)
from tbl
where translate(a, 'x0123456789', 'x') is null
and translate(b, 'x0123456789', 'x') is null;

这是做什么的:将字符 0123456789 翻译成 null,如果结果是 null,那么输入一定是全数字。 'x' 就在那里,因为要翻译的第三个参数不能是 null.

觉得我应该在这里添加这个,可能对其他读者有帮助。