spark count(distinct)over() 数据处理

1 篇文章 0 订阅

spark count(distinct)over() 数据处理

业务描述

有这么一个业务,需要过滤排除掉相同设备不同账号,以及相同账号不同设备的数据,只留下设备与账号一对一的数据:
如果从关系型数据库来看,A 多对对 B, 需要找出并保留 A一对一的B。

数据准备

设备id账号
1a
2b
2c
3b
3d
4d
5e
5e
/*
从数据上看只有(1,a),(5,e)满足一对一的要求,
设备2存在b/c两个账号,设备3存在b/d两个账号,账号d存在3、4两个设备
*/
-- 首先模拟hive处理数据, hive --version  =>  Hive 2.1.1-cdh6.2.0
WITH da AS(
SELECT 1 dev_id, 'a' acc UNION ALL
SELECT 2 dev_id, 'b' acc UNION ALL
SELECT 2 dev_id, 'c' acc UNION ALL
SELECT 3 dev_id, 'b' acc UNION ALL
SELECT 3 dev_id, 'd' acc UNION ALL
SELECT 4 dev_id, 'd' acc UNION ALL
SELECT 5 dev_id, 'e' acc UNION ALL
SELECT 5 dev_id, 'e' acc)
SELECT dev_id, acc FROM
(SELECT dev_id ,--设备
acc , --账号
COUNT(DISTINCT dev_id) OVER(PARTITION BY acc) sadd_cnt, --相同账号不同设备个数
COUNT(DISTINCT acc) OVER(PARTITION BY dev_id) sdda_cnt  --相同设备不同账号个数
from da) t where sadd_cnt = 1 and  sdda_cnt = 1;

在这里插入图片描述

出现问题

将hiveQL 移植到spark运行

spark.sql(
  s"""
     |SELECT dev_id, acc FROM
     |(SELECT dev_id ,--设备
     |acc , --账号
     |COUNT(DISTINCT dev_id) OVER(PARTITION BY acc) sadd_cnt, --相同账号不同设备个数
     |COUNT(DISTINCT acc) OVER(PARTITION BY dev_id) sdda_cnt  --相同设备不同账号个数
     |from (SELECT 1 dev_id, 'a' acc UNION ALL
     |SELECT 2 dev_id, 'b' acc UNION ALL
     |SELECT 2 dev_id, 'c' acc UNION ALL
     |SELECT 3 dev_id, 'b' acc UNION ALL
     |SELECT 3 dev_id, 'd' acc UNION ALL
     |SELECT 4 dev_id, 'd' acc UNION ALL
     |SELECT 5 dev_id, 'e' acc UNION ALL
     |SELECT 5 dev_id, 'e' acc) )
     |t where sadd_cnt = 1 and  sdda_cnt = 1
   """.stripMargin).show()

在这里插入图片描述

解决问题

参考hive解决 count(distinct)over()

WITH da AS (
SELECT 1 dev_id, 'a' acc UNION ALL
SELECT 2 dev_id, 'b' acc UNION ALL
SELECT 2 dev_id, 'c' acc UNION ALL
SELECT 3 dev_id, 'b' acc UNION ALL
SELECT 3 dev_id, 'd' acc UNION ALL
SELECT 4 dev_id, 'd' acc UNION ALL
SELECT 5 dev_id, 'e' acc UNION ALL
SELECT 5 dev_id, 'e' acc)
SELECT dev_id, acc FROM
(SELECT  dev_id ,--设备
acc , --账号
SIZE(COLLECT_SET( dev_id) OVER(PARTITION BY acc)) sadd_cnt, --相同账号不同设备个数
SIZE(COLLECT_SET( acc) OVER(PARTITION BY dev_id)) sdda_cnt  --相同设备不同账号个数
FROM da) t WHERE sadd_cnt = 1 AND  sdda_cnt = 1;

在这里插入图片描述

改用spark scala代码

spark.sql(
  s"""
     |WITH da AS (
     |SELECT 1 dev_id, 'a' acc UNION ALL
     |SELECT 2 dev_id, 'b' acc UNION ALL
     |SELECT 2 dev_id, 'c' acc UNION ALL
     |SELECT 3 dev_id, 'b' acc UNION ALL
     |SELECT 3 dev_id, 'd' acc UNION ALL
     |SELECT 4 dev_id, 'd' acc UNION ALL
     |SELECT 5 dev_id, 'e' acc UNION ALL
     |SELECT 5 dev_id, 'e' acc)
     |SELECT dev_id, acc FROM
     |(SELECT  dev_id ,--设备
     |acc , --账号
     |SIZE(COLLECT_SET( dev_id) OVER(PARTITION BY acc)) sadd_cnt, --相同账号不同设备个数
     |SIZE(COLLECT_SET( acc) OVER(PARTITION BY dev_id)) sdda_cnt  --相同设备不同账号个数
     |FROM da) t WHERE sadd_cnt = 1 AND  sdda_cnt = 1
   """.stripMargin).show()

在这里插入图片描述

参考站点

HIVE----count(distinct ) over() 无法使用解决办法https://www.cnblogs.com/luckyfruit/p/13093203.html

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值