加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

[Hive]Hive中LIKE查询使用通配符'%'的一个BUG--当转义符'\'遇到通配符'%'或'_'

(2012-03-01 17:15:46)
标签:

hive

转义

通配

bug

like

分类: Hadoop Hive

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中等价的查询:

SELECT * FROM T001 WHERE COL1 LIKE ‘ABC\\%’;

建议在Hive中用正则实现:

SELECT * FROM T001 WHERE COL1 REGEXP ‘^ABC\\’;

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有