分享

使用hive distinct或group by 去重复,遇到奇怪问题

songy 发表于 2015-12-15 12:03:49 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 14 23753
本帖最后由 songy 于 2015-12-15 13:06 编辑

使用hive distinct或group by 去重复,遇到奇怪问题:
1:我用hive sql, 使用DISTINCT ,或GROUP BY去重复,得到的查询结果为560条。
2:然后我不去重,把所有结果全部查出来,再用shell 对结果去重,结果为557条。
3:接着对两次的结果做了处理,已经找出差异的3条数据的id,返回去查询这3个id,同样使用distinct能查到,不使用却查不到结果。

使用group by 语句:
hive -e 'SELECT user_id FROM log.user_login WHERE login_time BETWEEN UNIX_TIMESTAMP("2015-12-10 00:00:00") AND UNIX_TIMESTAMP("2015-12-10 23:59:59") group by user_id  order by user_id;'
结果:
91266439
91933190
92005120
92762464
95589779
96798858
97089159
97558244
Time taken: 97.044 seconds, Fetched: 560 row(s)

使用distinct 语句:
hive -e 'SELECT DISTINCT user_id FROM log.user_login WHERE login_time BETWEEN UNIX_TIMESTAMP("2015-12-10 00:00:00") AND UNIX_TIMESTAMP("2015-12-10 23:59:59") order by user_id;'
结果与group by 一样是 560 row(s)


先全部查询,再手动去重:
hive -e 'SELECT user_id FROM log.user_login WHERE login_time BETWEEN UNIX_TIMESTAMP("2015-12-10 00:00:00") AND UNIX_TIMESTAMP("2015-12-10 23:59:59") ;'  | awk '{ array[$0]=$0 }  END{ for( id in array ){ print id } }' | sort | nl

结果为557条:
   550  91266439
   551  91933190
   552  92005120
   553  92762464
   554  95589779
   555  96798858
   556  97089159
   557  97558244


然后找出差异的3条数据,单独查询:
不使用distinct ,查不到:
hive -e 'SELECT user_id FROM log.user_login WHERE login_time BETWEEN UNIX_TIMESTAMP("2015-12-10 00:00:00") AND UNIX_TIMESTAMP("2015-12-10 23:59:59") and user_id in ( "14616294","14623531","25003520") ;'

使用distinct ,能查到差异的3条数据:
hive -e 'SELECT distinct user_id FROM log.user_login WHERE login_time BETWEEN UNIX_TIMESTAMP("2015-12-10 00:00:00") AND UNIX_TIMESTAMP("2015-12-10 23:59:59") and user_id in  ( "14616294","14623531","25003520") ;'
OK
14623531
14616294
25003520

怎么会这样奇怪?? 在执行语句过程中我发现使用distinct 或 group by 用到了mapreduce的过程,我也不知道是不是mr的问题,不知道接下来该怎么找问题??



进一步测试,有了意外发现,我把login_time字段也同时查询出来,发现多的这几个id的login_time 时间并不在我限定的时间范围内:
使用 distinct:
hive -e 'SELECT distinct user_id, login_time FROM log.user_login  WHERE login_time BETWEEN UNIX_TIMESTAMP("2015-12-10 00:00:00") AND UNIX_TIMESTAMP("2015-12-10 23:59:59") and user_id in ( "14616294","14623531","25003520") ;'

使用 group by:
hive -e 'SELECT user_id, login_time FROM log.user_login  WHERE login_time BETWEEN UNIX_TIMESTAMP("2015-12-10 00:00:00") AND UNIX_TIMESTAMP("2015-12-10 23:59:59") and user_id in ( "14616294","14623531","25003520")  group by user_id, login_time ;'

均得到相同结果:
14616294      1449772753
25003520      1449807672
14623531      1449772517
14616294      1449772662
Time taken: 68.644 seconds, Fetched: 4 row(s)

然后转换时间戳如下(全为2015-12-11):
1449772753
2015-12-11 02:39:13
1449807672
2015-12-11 12:21:12
1449772517
2015-12-11 02:35:17
1449772662
2015-12-11 02:37:42



很奇怪 为何distinct /group by 会把2015-12-11日的这几个数据查出来, 我明明是要查2015-12-10 的。 为什么会出这个情况啊??

mr

mr

已有(14)人评论

跳转到指定楼层
cranberries8 发表于 2015-12-15 13:08:06
你的意思是利用hive来查的要比直接查出来手动排重的多 这三条:
14623531
14616294
25003520 ?
回复

使用道具 举报

songy 发表于 2015-12-15 13:10:46
cranberries8 发表于 2015-12-15 13:08
你的意思是利用hive来查的要比直接查出来手动排重的多 这三条:
14623531
14616294

是的,而且后面我把这三条的时间字段也查出来,发现并不在我限定的时间范围内,很奇怪,有没有什么好办法?
回复

使用道具 举报

songy 发表于 2015-12-15 13:13:36
cranberries8 发表于 2015-12-15 13:08
你的意思是利用hive来查的要比直接查出来手动排重的多 这三条:
14623531
14616294

我限定的时间是  2015-12-10 BETWEEN UNIX_TIMESTAMP("2015-12-10 00:00:00") AND UNIX_TIMESTAMP("2015-12-10 23:59:59")
多的这几天的时间是2015-12-11的,却也被查出来了。。。。。。

回复

使用道具 举报

cranberries8 发表于 2015-12-15 13:25:30
songy 发表于 2015-12-15 13:10
是的,而且后面我把这三条的时间字段也查出来,发现并不在我限定的时间范围内,很奇怪,有没有什么好办法 ...

实际上多了distinct 或者 group by 后就会一个 reduce的过程。
条件过滤是在map阶段执行的,感觉没啥子差啊 。
你试试不用 between 。。。 and 。。 换成 < and < 试试
回复

使用道具 举报

songy 发表于 2015-12-15 13:33:08
cranberries8 发表于 2015-12-15 13:25
实际上多了distinct 或者 group by 后就会一个 reduce的过程。
条件过滤是在map阶段执行的,感觉没啥子 ...


按照你说的,我把between and 改成 >= 和 <=,仍然能把2015-12-11好的查出来,。。
hive -e 'SELECT distinct user_id, login_time FROM log.user_login  WHERE login_time >= UNIX_TIMESTAMP("2015-12-10 00:00:00") AND and login_time <= UNIX_TIMESTAMP("2015-12-10 23:59:59") and user_id in ( "14616294","14623531","25003520") ;'
回复

使用道具 举报

cranberries8 发表于 2015-12-15 13:37:57
songy 发表于 2015-12-15 13:33
按照你说的,我把between and 改成 >= 和

我用你的数据测试了一下 没问题啊 ,加distinct 也查不出来,没问题啊
回复

使用道具 举报

cranberries8 发表于 2015-12-15 13:44:24
songy 发表于 2015-12-15 13:33
按照你说的,我把between and 改成 >= 和

有没有可能你的各个机器的时区不同步的情况?
回复

使用道具 举报

songy 发表于 2015-12-15 13:53:16
cranberries8 发表于 2015-12-15 13:44
有没有可能你的各个机器的时区不同步的情况?

非常感谢你帮忙看我的问题。

我检查了机器的时区,都没有问题:
[root@namenode ~]#
[root@namenode ~]#
[root@namenode ~]# ansible datanode -m shell -a 'date -R; date +"%F %T"'
datanode1 | success | rc=0 >>
Tue, 15 Dec 2015 13:50:10 +0800
2015-12-15 13:50:10

datanode3 | success | rc=0 >>
Tue, 15 Dec 2015 13:50:11 +0800
2015-12-15 13:50:11

datanode2 | success | rc=0 >>
Tue, 15 Dec 2015 13:50:11 +0800
2015-12-15 13:50:11

phpWeb | success | rc=0 >>
Tue, 15 Dec 2015 13:50:10 +0800
2015-12-15 13:50:10

phpTask | success | rc=0 >>
Tue, 15 Dec 2015 13:50:11 +0800
2015-12-15 13:50:11

datanode155 | success | rc=0 >>
Tue, 15 Dec 2015 13:50:11 +0800
2015-12-15 13:50:11

datanode219 | success | rc=0 >>
Tue, 15 Dec 2015 13:50:11 +0800
2015-12-15 13:50:11

datanode159 | success | rc=0 >>
Tue, 15 Dec 2015 13:50:12 +0800
2015-12-15 13:50:12

datanode215 | success | rc=0 >>
Tue, 15 Dec 2015 13:50:11 +0800
2015-12-15 13:50:11

datanode220 | success | rc=0 >>
Tue, 15 Dec 2015 13:50:11 +0800
2015-12-15 13:50:11

[root@namenode ~]# date -R; date +"%F %T"
Tue, 15 Dec 2015 13:50:18 +0800
2015-12-15 13:50:18
[root@namenode ~]#



回复

使用道具 举报

cranberries8 发表于 2015-12-15 13:57:39
你直接创建一个测试表
添加这几条数据:
14616294        1449772662
14616294        1449772753
14623531        1449772517
25003520        1449807672
用你的命令你看能查的出来不,我 这个环境是没问题的 ,查10号的不会出现11号的数据?
回复

使用道具 举报

12下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条