查找不是数字或预定义字符串的值
Posted
技术标签:
【中文标题】查找不是数字或预定义字符串的值【英文标题】:Find value that is not a number or a predefined string 【发布时间】:2022-01-08 00:54:57 【问题描述】:我必须测试 sql 表的列是否存在无效值和 NULL。
有效值为:任意数字和字符串 'n.v.' (有和没有点,以及在我的 sql 命令中列出的所有可能的组合)
到目前为止,我已经尝试过:
select count(*)
from table1
where column1 is null
or not REGEXP_LIKE(column1, '^[0-9,nv,Nv,nV,NV,n.v,N.v,n.V,N.V]+$');
正则表达式还匹配单个字符值 'n'、'N'、'v'、'V'(带有和不带有后面的点)。这不应该是这种情况,因为我只希望匹配 sql 命令中写入的确切字符组合。我猜这个问题与使用 REGEXP_LIKE 有关。有什么想法吗?
【问题讨论】:
【参考方案1】:我猜这个正则表达式会起作用:
NOT REGEXP_LIKE(column1, '^([0-9]+|n\.?v\.?)$', 'i')
请注意,,
不是分隔符,.
表示任何字符,\.
表示点字符本身,'i'
标志可用于忽略大小写而不是硬编码所有大小写组合字符。
【讨论】:
【参考方案2】:无需使用regexp
(大数据会提高性能)- 普通的旧TRANSLATE
足以进行验证。
请注意,第一个translate(column1,'x0123456789','x')
会从字符串中删除所有数字字符,因此如果以null
结尾,则字符串是可以的。
第二个translate(lower(column1),'x.','x')
从lowered 字符串中删除所有点,因此您期望得到nv
的结果。
为了避免n.....v....
的情况,您还限制了字符串长度。
select
column1,
case when
translate(column1,'x0123456789','x') is null or /* numeric string */
translate(lower(column1),'x.','x') = 'nv' and length(column1) <= 4 then 'OK'
end as status
from table1
COLUMN1 STATUS
--------- ------
1010101 OK
1012828n
1012828nv
n.....v....
n.V OK
测试数据
create table table1 as
select '1010101' column1 from dual union all -- OK numbers
select '1012828n' from dual union all -- invalid
select '1012828nv' from dual union all -- invalid
select 'n.....v....' from dual union all -- invalid
select 'n.V' from dual; -- OK nv
【讨论】:
【参考方案3】:你可以使用:
select count(*)
from table1
WHERE TRANSLATE(column1, ' 0123456789', ' ') IS NULL
OR LOWER(column1) IN ('nv', 'n.v', 'nv.', 'n.v.');
其中,对于样本数据:
CREATE TABLE table1 (column1) AS
SELECT '12345' FROM DUAL UNION ALL
SELECT 'nv' FROM DUAL UNION ALL
SELECT 'NV' FROM DUAL UNION ALL
SELECT 'nV' FROM DUAL UNION ALL
SELECT 'n.V.' FROM DUAL UNION ALL
SELECT '...................n.V.....................' FROM DUAL UNION ALL
SELECT '..nV' FROM DUAL UNION ALL
SELECT 'n..V' FROM DUAL UNION ALL
SELECT 'nV..' FROM DUAL UNION ALL
SELECT 'xyz' FROM DUAL UNION ALL
SELECT '123nv' FROM DUAL;
输出:
COUNT(*) 5
或者,如果您想要任意数量的.
,那么:
select count(*)
from table1
WHERE TRANSLATE(column1, ' 0123456789', ' ') IS NULL
OR REPLACE(LOWER(column1), '.') = 'nv';
哪些输出:
COUNT(*) 9
db小提琴here
【讨论】:
以上是关于查找不是数字或预定义字符串的值的主要内容,如果未能解决你的问题,请参考以下文章