在多年取数中,第一次遇到需要用笛卡尔积join的场景,记录一下
场景一:
描述:取10月每日近三十天的购物情况,比如,取10月1日的用户在过去30天(含10月1日)的购物情况,源数据tmp1如下
| 用户id (user_id) | 日期 (date) | 购物件数(buys) |
| a | 2021-09-01 | 1 |
| a | 2021-10-01 | 3 |
| a | 2021-09-28 | 1 |
| b | 2021-09-05 | 4 |
| b | 2021-10-01 | 1 |
| b | 2021-09-28 | 5 |
结果
| 日期 (date) | 购物件数(buys) | 人数 |
| 2021-10-01 | 4 | 1 |
| 2021-10-01 | 10 | 1 |
简单维度的sql如下
select buys,count(user_id) as rs
from (
select user_id
,sum(buys) buys
,'2021-10-01' as date
from tmp1
where datediff('2021-10-01',date) between 0 and 29
group by user_id
)t
group by buys
场景一升级:上述是每次只可以跑当天的数据,如果是要跑10月1日-10月31日的数据呢?比如如下呢?不可能一个一个去取,要怎么去写脚本呢?我们知道就是要近三十天 用datediff函数,比如上述datediff('2021-10-01',date) between 0 and 29 ,难点在于之前'2021-10-01' 是我们手动写的,怎么让它自动取呢
| 日期 (date) | 购物件数(buys) | 人数 |
| 2021-10-01 | 4 | 1 |
| 2021-10-01 | 10 | 1 |
| 2021-10-02 | 3 | 1 |
| 2021-10-02 | 5 | 5 |
| 2021-10-03 | 3 | 1 |
| 2021-10-03 | 7 | 9 |
| ........ |
1、首先取出需要的时间段,不可能手写,我就直接从现有的表取,下述是一种除重的写法
select date
from tmp1
where date between '2021-10-01' and '2021-10-31' --取出想要计算的时间范围
group by date
2、把每天符合条件的记录筛选出来
--如下脚本 先算两个表的笛卡尔积,再执行where条件
select t1.date as date1,t2.*
from (select date
from tmp1
where date between '2021-10-01' and '2021-10-31' --取出想要计算的时间范围
group by date
)t1
left join tmp1 t2 --此处是算join的笛卡尔积,用join、left join,inner join 都一样,结果是第一个表的n行*第二个表的m行=n*m行
--on datediff(t1.date,t2.date) between 0 and 29 --hive里不支持这种写法
where datediff(t1.date,t2.date) between 0 and 29
3、然后就是简单的group by 啦
总结:1、join的on条件不能放算式
2、join的笛卡尔积,用join、left join,inner join 结果都一样,结果是第一个表的n行*第二个表的m行=n*m行,运行较慢
3、left join on 后接where 先执行left 后执行where



