hive的like查新_[Hive]Hive中LIKE查询使⽤通配符%的⼀个
BUG--当转。。。
在Hive开发过程中遇到这样⼀个问题:例如表T001的字段col1⾥⾯存有’ABC\DEF’这样的数据,在Oracle中,我可以通过下⾯这样的SQL将其查出:SELECT * FROM T001 WHERE COL1 LIKE ‘ABC\%’;
‘\’不会将’%’进⾏转义,因为没有使⽤ESCAPE ‘\’语法。但是到了Hive⾥就不⾏了,SELECT * FROM T001 WHERE COL1 LIKE
‘ABC\%’;不会得到想要的结果。不过Hive有些特别,因为’\’默认就是转义字符,因此,其实和上⾯Oracle中等价的写法应该是
对’\’转义⼀次,即:SELECT * FROM T001 WHERE COL1 LIKE
‘ABC\\%’;但是很遗憾,还是得不到想要的结果。
为了⼀探究竟,我做了些简单的实验:在Hive中插⼊⼀条记录(省略部分打印信息):
hive> INSERT OVERWRITE TABLE T001 SELECT '\\' FROM
DUAL;
1 Rows loaded to T001
OK
hive> SELECT * FROM T001;
OK
\
然后进⾏LIKE查询测试:
hive> SELECT * FROM T001 WHERE COL1 LIKE
'\\';
OK
\
这⼀步查询在意料当中,再加⼊'%'试⼀下:
hive> SELECT * FROM T001 WHERE COL1 LIKE
'%\\';
OK
\
可以看到,将’%’放到前⾯没有问题,再把’%’放到后⾯看看⾏不⾏:
hive> SELECT * FROM T001 WHERE COL1 LIKE
'\\%';
OK
这回问题暴露了,没有查出结果。我猜想,Hive解析时是⽤’\’把’%’给转义了,于是测试了⼀下:
hive> INSERT OVERWRITE TABLE T001 SELECT '%'
FROM DUAL;
1 Rows loaded to T001
OK
hive> SELECT * FROM T001;
OK
%
hive> SELECT * FROM T001 WHERE COL1 LIKE
'\\%';
OK
%
结果果然不出所料!但问题是,我现在想让’%’作为通配符,⽽不想让’\’将其转义,难道就做不到吗?
Hive⾥没有ESCAPE语法,不能通过这种⽅法解决了,在尝试⼀下其他⽅法:既然’\’是转义字符,能把’%’转义掉,那可不可以多加⼀个’\’把’\’给转义了呢?
SELECT
* FROM T001 WHERE COL1 LIKE ‘ABC\\\\%’;
结果还是不⾏!于是我⼜测试了⼀个⼩例⼦:
hive> INSERT OVERWRITE TABLE T001 SELECT
'\\\\' FROM DUAL;
1 Rows loaded to T001
OK
hive> SELECT * FROM T001;
OK
\\
hive> SELECT * FROM T001 WHERE COL1 LIKE
'\\\\';
OK
\\
恩,不出所料。
hive> SELECT * FROM T001 WHERE COL1 LIKE
'%\\';
OK
\\
还是不出所料。
hive> SELECT * FROM T001 WHERE COL1 LIKE
'\\%';
OK
这个已经知道查不出来了,因为上⾯的实验已经证明这个查询匹配到的是’%’
hive> SELECT * FROM T001 WHERE COL1 LIKE
'\\\\%';
OK
还是查不出来,进⼀步实验可以得知这个查询匹配到的是’\%’于是我得出结论:‘\’与’%’连在⼀起⽤在LIKE中时,’\’总是将’%’转义成普通字符,即’%’失去了通配符的作⽤。本来’\’转义应该是从左向右解析的,但是当’\’遇到’%’时似乎优先级更⾼,总是优先和’%’结合。可想⽽知,通配符’_’也有同样的问题。我认为这应该算是Hive的⼀个BUG。如果确实想写和Oracle中等价的查询:
regexp likeSELECT
* FROM T001 WHERE COL1 LIKE ‘ABC\\%’;
建议在Hive中⽤正则实现:
SELECT
* FROM T001 WHERE COL1 REGEXP ‘^ABC\\’;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论