Netezza SQL正则匹配结果少于Like函数问题求助
我来帮你拆解一下这个问题的核心原因,你这里的问题完全是正则表达式的匹配逻辑加上后续判断逻辑的双重偏差导致的:
1. 先明确你的LIKE逻辑到底在做什么
你的LIKE语句:
where trim(upper(a.MRCH_NME)) like '%CNA %'
逻辑非常直白:只要处理后的商户名称任何位置存在"CNA "(CNA加空格)这个子串,就会被命中。不管这个子串前面有乱码、符号,后面有其他内容,只要有这个子串就符合条件,所以你列出的那些字符串(比如!C CNA INT ARR、*CNA PLATZ 0400)都能被匹配到。
2. 你的正则逻辑哪里错了?
你用的正则.*CNA\s配合array_combine后判断等于'CNA',这里有两个致命问题:
- 正则匹配范围错误:
.*CNA\s的意思是匹配从字符串开头一直到"CNA"加空白字符的全部内容,而不是只提取"CNA"本身。比如对于!C CNA INT ARR,这个正则会匹配出!C CNA(注意末尾的空格),而不是你想要的"CNA"。 - 后续判断逻辑错误:你把提取到的匹配内容用
|拼接后,要求结果等于'CNA',但实际上提取出来的是包含前缀和空格的长字符串,肯定不可能等于'CNA',所以那些符合LIKE条件的记录全部被过滤掉了。
3. 为什么你列出的字符串没被匹配?
拿!C CNA INT ARR举个具体例子:
- 处理后的字符串是
!C CNA INT ARR(upper和trim后无变化) - 正则
.*CNA\s匹配的是从开头到"CNA "的完整片段:!C CNA regexp_extract_all返回这个片段,array_combine(...)得到的结果是!C CNA,显然不等于'CNA',所以这条记录不会被选中。
其他几个未匹配的字符串都是同样的道理:正则提取的是包含前缀和空格的长内容,和你判断的'CNA'完全不相等。
4. 怎么用正则实现和LIKE完全一致的效果?
最直接的方式是用Netezza的regexp_like函数直接判断存在性,写法如下:
where regexp_like(trim(upper(a.MRCH_NME)), 'CNA\s')
因为你已经用了upper统一转大写,所以不需要再加'i'忽略大小写的参数,这个语句的逻辑和你的LIKE完全一致:只要处理后的字符串中存在"CNA加空格"的子串就命中。
如果一定要坚持用regexp_extract_all的方式(其实没必要),可以调整正则只提取"CNA",并判断数组中是否包含这个值:
where array_contains(regexp_extract_all(trim(upper(a.MRCH_NME)), 'CNA(?=\s)'), 'CNA')
这里(?=\s)是正向预查,确保CNA后面跟着空格,但只提取"CNA"本身,然后用array_contains判断提取结果里是否有目标值。
内容的提问来源于stack exchange,提问作者Atlas_Apple
相关产品推荐
相关产品推荐

