Oracle SQL:使用非数字字符过滤行

时间:2016-10-19 11:08:53

标签: sql regex oracle numeric

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

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

从第3个查询开始,我预计会看到(962060-17)= 962043。为什么它仍然是962060?像这样的alternative查询也给出了相同的答案:

#!/bin/bash

while IFS= read -r -d '' file; do
    echo "$file"
    # Do whatever you want to do with your file here
done < <(find someDir/ -maxdepth 1 -mindepth 1 -type f -print0 | sort -z)

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

2 个答案:

答案 0 :(得分:4)

如果你使用正则表达式,你应该考虑到字符串的任何部分可以匹配为正则表达式。根据你的例子,你应该指定整个字符串应该只保留数字^ - 是字符串$的开始 - 是结束。您可以使用\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+$') )

答案 1 :(得分:1)

我知道您特意要求使用正则表达式解决方案,但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

以为我应该在这里添加它,可能对其他读者有帮助。