我们这次 Spark-sql 操作中所有的数据均来自 Hive,首先在 Hive 中创建表,,并导入数据。一共有 3 张表: 1 张用户行为表,1 张城市表,1 张产品表
创建目录/opt/module/input
上传三个数据文件
city_info.txt
product_info.txt
user_visit_action.txt
进入hive中执行
CREATE TABLE `user_visit_action`(
`date` string,
`user_id` bigint,
`session_id` string,
`page_id` bigint,
`action_time` string,
`search_keyword` string,
`click_category_id` bigint,
`click_product_id` bigint,
`order_category_ids` string,
`order_product_ids` string,
`pay_category_ids` string,
`pay_product_ids` string,
`city_id` bigint)
row format delimited fields terminated by '\t';
load data local inpath '/opt/module/input/user_visit_action.txt' into table user_visit_action;
CREATE TABLE `product_info`(
`product_id` bigint,
`product_name` string,
`extend_info` string)
row format delimited fields terminated by '\t';
load data local inpath '/opt/module/input/product_info.txt' into table product_info;
CREATE TABLE `city_info`(
`city_id` bigint,
`city_name` string,
`area` string)
row format delimited fields terminated by '\t';
load data local inpath '/opt/module/input/city_info.txt' into table city_info;
查看数据是否加载成功
select * from city_info;
select * from product_info;
select * from user_visit_action;
创建一个test表,并插入6条数据。
CREATE TABLE test
(
a INT,
b INT,
c CHAR
)
插入数据
INSERT INTO test VALUES(1,3,'E')
INSERT INTO test VALUES(2,4,'A')
INSERT INTO test VALUES(3,2,'D')
INSERT INTO test VALUES(3,5,'B')
INSERT INTO test VALUES(4,2,'C')
INSERT INTO test VALUES(2,4,'B')
SELECT * from test
a b c
1 3 E
2 4 A
3 2 D
3 5 B
4 2 C
2 4 B
(6 行受影响)
1、整个结果集是一个分组,以a进行排名
SELECT a,b,c,rank () OVER (ORDER BY a) rank FROM test
a b c rank
1 3 E 1
2 4 A 2
2 4 B 2
3 2 D 4
3 5 B 4
4 2 C 6
(6 行受影响)
2、整个结果集是一个分组,以b进行排名
SELECT a,b,c,rank () OVER (ORDER BY b) rank FROM test
a b c rank
3 2 D 1
4 2 C 1
1 3 E 3
2 4 A 4
2 4 B 4
3 5 B 6
(6 行受影响)
3、以a,b进行分组,在每个组内以b进行排名。分了5个组,第2行跟第3行是一个组,其他的每行是一个组。在第2行与第3行的组内以b排名,并列为1
SELECT a,b,c,rank () OVER (PARTITION BY a,b ORDER BY b) rank FROM test
a b c rank
1 3 E 1
2 4 A 1
2 4 B 1
3 2 D 1
3 5 B 1
4 2 C 1
(6 行受影响)
4、以a,b进行分组,在每个组内以c进行排名。分了5个组,第2行跟第3行是一个组,其他的每行是一个组。在第2行与第3行的组内以c排名,由于c列一个是A,一个是B,所以Rank分别为1、2。
SELECT a,b,c,rank () OVER (PARTITION BY a,b ORDER BY c) rank FROM test
a b c rank
1 3 E 1
2 4 A 1
2 4 B 2
3 2 D 1
3 5 B 1
4 2 C 1
(6 行受影响)
总结:
1、partition by用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组。
2、Rank 是在每个分组内部进行排名的。
这里的热门商品是从点击量的维度来看的,计算各个区域前三大热门商品,并备注上每个商品在主要城市中的分布比例,超过两个城市用其他显示。
例如:
地区 商品名称 点击次数
华北 商品 A 100000
华北 商品 P 80200
华北 商品 M 40000
东北 商品 J 92000
查询出来所有的点击记录,并与 city_info 表连接,
得到每个城市所在的地区,与Product_info 表连接得到产品名称
连接三张表的数据,获取完整的数据(只有点击)
将数据根据地区,商品名称分组
统计商品点击次数总和,取Top3
spark.sql(
"""
select
*
from (
select
*,
rank() over( partition by area order by clickCnt desc ) as rank
from (
select
area,
product_name,
count(*) as clickCnt
from (
select
a.*,
p.product_name,
c.area,
c.city_name
from user_visit_action a
join product_info p on a.click_product_id = p.product_id
join city_info c on a.city_id = c.city_id
where a.click_product_id > -1
) t1 group by area, product_name
) t2
) t3 where rank <= 3
""")
.show