hive:通过join连接实现排列组合

  • 问题
    有一些订单信息,记录了用户是否购买过某个产品。想统计一下同时购买过任意两个产品的用户,类似于组合;还有购买过两个产品并且分购买先后顺序的用户,比如先购买了300055再购买300056、先购买了300056再购买300055,分两种统计,类似于排列。如果用其他语言的话,可以考虑采用循环,但是在hive中循环不太好实现,可以采用join实现。
    在这里插入图片描述

  • 解决方法
    通过uid来连接,然后限定不同的条件实现排列组合。

    • 连接,通过uid来关联
      在这里插入图片描述
    • 同时购买过任意两种产品的用户,C(3,2);限制条件tmp1.result=1 and tmp2.result=1 and tmp1.pid<tmp2.pid
      在这里插入图片描述
    • 购买过任意两种产品中至少一个产品的用户,C(3,2);限制条件where (tmp1.result=1 or tmp2.result=1) and (tmp1.pid<tmp2.pid)
      在这里插入图片描述
    • 同时购买过任意两种产品且有先后顺序的用户,A(3,2);限制条件tmp1.result=1 and tmp2.result=1 and tmp1.pid!=tmp2.pid
      在这里插入图片描述
    • 购买过任意两种产品中至少一个产品且有先后顺序的用户,A(3,2);限制条件where (tmp1.result=1 or tmp2.result=1) and (tmp1.pid!=tmp2.pid)
      在这里插入图片描述
    select
        distinct
        tmp1.uid as uid,
        concat(tmp1.pid,"_",tmp2.pid) as pid,  --两两组合
        concat(tmp1.result,"_",tmp2.result) as result,  --两两组合
    from
        (select
            pid,
            uid,
            result
        from test) tmp1
    full join
        (select
            pid,
            uid,
            result
        from test) tmp2
    on tmp1.uid=tmp2.uid
    where tmp1.result=1 and tmp2.result=1  and tmp1.pid<tmp2.pid  --产品两两组合,且同时购买
    --where (tmp1.result=1 or tmp2.result=1) and (tmp1.pid<tmp2.pid)  --产品两两组合,且购买过其中至少一种产品
    --where tmp1.result=1 and tmp2.result=1  and tmp1.pid!=tmp2.pid  --产品两两组合,同时购买且有先后顺序
    --where (tmp1.result=1 or tmp2.result=1) and (tmp1.pid!=tmp2.pid)  --产品两两组合,购买过其中至少一种产品且有先后顺序
    

    ps:初衷是通过撰写博文记录自己所学所用,实现知识的梳理与积累;将其分享,希望能够帮到面临同样困惑的小伙伴儿。如发现博文中存在问题,欢迎随时交流~~

### 大数据开发 HiveSQL 笔试题目及答案 #### 题目 1:连接实现连接是一种特殊的连接方式,表与其自身进行连接。这通常用于查找具有层次结构的数据。 ```sql SELECT e.employee_id, m.manager_name FROM employees AS e JOIN employees AS m ON e.manager_id = m.employee_id; ``` 此查询展示了如何通过员工表找到每位员工对应的经理名称[^1]。 #### 题目 2: 窗口分析函数实现 窗口函数允许执行聚合计算而不减少输入行的数量。下面的例子展示了一个典型的排名场景: ```sql SELECT employee_id, salary, DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) as rank FROM salaries; ``` 这段代码按部门分区并根据薪水降序排列来分配密集等级。 #### 题目 3: Top N 查询 为了获取每个类别的前几名记录,可以使用窗口函数配合 `LIMIT` 或者子查询的方法: ```sql WITH RankedSales AS ( SELECT product_category, sales_amount, ROW_NUMBER() OVER(PARTITION BY product_category ORDER BY sales_amount DESC) rn FROM sales_data ) SELECT * FROM RankedSales WHERE rn <= 5; -- 获取每种类目的前五名销售量商品 ``` 这里利用了CTE(公用表表达式)以及ROW_NUMBER窗口函数实现了分类下的top n选取. #### 题目 4: 使用 CONCAT 和 CONCAT_WS 函数 这两个字符串拼接函数的区别在于后者可以在多个参数间加入指定分隔符。 ```sql -- 单纯地把两列内容连在一起 SELECT concat(firstname,' ',lastname) full_name FROM users; -- 加入逗号作为分隔符链接多列 SELECT concat_ws(',', firstname, lastname, email) info_string FROM users; ``` 上述例子分别演示了两种不同情况下应该如何选用合适的字符串组合方法[^3]. #### 题目 5: LOAD DATA 命令语法 当需要加载外部文件到Hive表时,可采用如下命令格式: ```sql LOAD DATA LOCAL INPATH '/path/to/local/file' INTO TABLE my_table; ``` 这条语句指定了本地路径中的文件被导入至名为my_table的目标表格中[^4]. #### 题目 6: WHERE vs HAVING 的区别 理解两者之间的差异对于写出高效的查询至关重要。WHERE适用于过滤单条记录;而HAVING则针对已经完成GROUP BY操作后的结果集做进一步筛选。 ```sql -- 正确用法示范 SELECT region, COUNT(*) num_stores FROM stores WHERE open_date >= '2020-01-01' GROUP BY region HAVING COUNT(*) > 10; ``` 该片段说明了何时应该应用WHERE条件而非HAVING来进行初步的数据裁剪[^5].
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值