既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
drop database if exists shopping cascade
create database shopping
**Use database**
use shopping
**Create external table**
**创建四张对应的外部表,也就是本次项目中的近源表。**
create external table if not exists ext_customer_details(
customer_id string,
first_name string,
last_name string,
email string,
gender string,
address string,
country string,
language string,
job string,
credit_type string,
credit_no string
)
row format delimited fields terminated by ‘,’
location ‘/tmp/shopping/data/customer/’
tblproperties(‘skip.header.line.count’=‘1’)
create external table if not exists ext_transaction_details(
transaction_id string,
customer_id string,
store_id string,
price double,
product string,
buydate string,
buytime string
)
row format delimited fields terminated by ‘,’
location ‘/tmp/shopping/data/transaction’
tblproperties(‘skip.header.line.count’=‘1’)
create external table if not exists ext_store_details(
store_id string,
store_name string,
employee_number int
)
row format delimited fields terminated by ‘,’
location ‘/tmp/shopping/data/store/’
tblproperties(‘skip.header.line.count’=‘1’)
create external table if not exists ext_store_review(
transaction_id string,
store_id string,
review_score int
)
row format delimited fields terminated by ‘,’
location ‘/tmp/shopping/data/review’
tblproperties(‘skip.header.line.count’=‘1’)
##### 通过UDF自定义 MD5加密函数
**Create MD5 encryption function**
这里通过UDF自定义 MD5加密函数 ,对地址、邮箱等信息进行加密。
– md5 udf自定义加密函数
–add jar /opt/soft/data/md5.jar
–create temporary function md5 as ‘com.shopping.services.Encryption’
–select md5(‘abc’)
–drop temporary function encrymd5
**Clean and Mask customer\_details 创建明细表**
create table if not exists customer_details
as select customer_id,first_name,last_name,md5(email) email,gender,md5(address) address,country,job,credit_type,md5(credit_no)
from ext_customer_details
##### 对表内容进行检查,为数据清洗做准备
**Check ext\_transaction\_details data**
对`transaction`表的`transaction_id`进行检查,查看重复的、错误的、以及空值的数量。
这里从表中我们可以看到`transaction_id`存在100个重复的值。
with
t1 as (select ‘countrow’ as status,count(transaction_id) as val from ext_transaction_details),
t2 as (select ‘distinct’ as status,(count(transaction_id)-count(distinct transaction_id)) as val from ext_transaction_details),
t3 as (select ‘nullrow’ as status,count(transaction_id) as val from ext_transaction_details where transaction_id is null),
t4 as (select ‘errorexp’ as status,count(regexp_extract(transaction_id,‘^([0-9]{1,4})$’,0)) as val from ext_transaction_details)
select * from t1 union all select * from t2 union all select * from t3 union all select * from t4

**Clean transaction\_details into partition table**
create table if not exists transaction_details(
transaction_id string,
customer_id string,
store_id string,
price double,
product string,
buydate string,
buytime string
)
partitioned by (partday string)
row format delimited fields terminated by ‘,’
stored as rcfile
**开启动态分区**
set hive.exec.dynamic.partition=true
set hive.exec.dynamic.partition.mode=nonstrict
##### 开启动态分区,通过窗口函数对数据进行清洗
**Clear data and import data into transaction\_details**
– partday 分区 transaction_id 重复
select if(t.ct=1,transaction_id,concat(t.transaction_id,‘_’,t.ct-1))
transaction_id,customer_id,store_id,price,product,buydate,buytime,date_format(buydate,‘yyyy-MM’)
as partday
from (select *,row_number() over(partition by transaction_id) as ct
from ext_transaction_details) t
insert into transaction_details partition(partday)
select if(t.ct=1,transaction_id,concat(t.transaction_id,‘_’,t.ct-1)) transaction_id,customer_id,store_id,price,product,buydate,buytime,date_format(regexp_replace(buydate,‘/’,‘-’),‘yyyy-MM’)
as partday from (select *,row_number() over(partition by transaction_id) as ct
from ext_transaction_details) t
* **row\_number() over(partition by transaction\_id)** 窗口函数 :从1开始,按照顺序,生成分组内记录的序列,row\_number()的值不会存在重复,当排序的值相同时,按照表中记录的顺序进行排列 这里我们对分组的transaction\_id
* `if(t.ct=1,transaction_id,concat(t.transaction_id,'_',t.ct-1))` 如果满足`ct=1`,就是`transaction_id`,否则进行字符串拼接生成新的id

**Clean store\_review table**
create table store_review
as select transaction_id,store_id,nvl(review_score,ceil(rand()*5))
as review_score from ext_store_review
**NVL(E1, E2)的功能为:如果E1为NULL,则函数返回E2,否则返回E1本身。**

我们可以看到表中的数据存在空值,通过NVL函数对数据进行填充。
show tables

通过清洗后的近源表和明细表如上。
##### 数据分析
##### Customer分析
* 找出顾客最常用的信用卡
select credit_type,count(credit_type) as peoplenum from customer_details
group by credit_type order by peoplenum desc limit 1
* 找出客户资料中排名前五的职位名称
select job,count(job) as jobnum from customer_details
group by job
order by jobnum desc
limit 5
* 在美国女性最常用的信用卡
select credit_type,count(credit_type) as femalenum from customer_details
where gender=‘Female’
group by credit_type
order by femalenum desc
limit 1
* 按性别和国家进行客户统计
select count(*) as customernum,country,gender from customer_details
group by country,gender
##### Transaction分析
* 计算每月总收入
select partday,sum(price) as countMoney from transaction_details group by partday
* 计算每个季度的总收入
**Create Quarter Macro 定义季度宏**,将时间按季度进行划分
create temporary macro
calQuarter(dt string)
concat(year(regexp_replace(dt,‘/’,‘-’)),‘年第’,ceil(month(regexp_replace(dt,‘/’,‘-’))/3),‘季度’)
select calQuarter(buydate) as quarter,sum(price) as sale
from transaction_details group by calQuarter(buydate)

* 按年计算总收入
create temporary macro calYear(dt string) year(regexp_replace(dt,‘/’,‘-’))
select calYear(buydate) as year,sum(price) as sale from transaction_details group by calYear(buydate)
* 按工作日计算总收入
create temporary macro calWeek(dt string) concat(‘星期’,dayofweek(regexp_replace(dt,‘/’,‘-’))-1)
select concat(‘星期’,dayofweek(regexp_replace(buydate,‘/’,‘-’))-1) as week,sum(price) as sale
from transaction_details group by dayofweek(regexp_replace(buydate,‘/’,‘-’))

* 按时间段计算总收入(需要清理数据)
select concat(regexp_extract(buytime,‘[0-9]{1,2}’,0),‘时’) as time,sum(price) as sale from transaction_details group by regexp_extract(buytime,‘[0-9]{1,2}’,0)

* 按时间段计算平均消费
**Time macro**
create temporary macro calTime(time string) if(split(time,’ ‘)[1]=‘PM’,regexp_extract(time,’[0-9]{1,2}‘,0)+12,
if(split(time,’ ‘)[1]=‘AM’,regexp_extract(time,’[0-9]{1,2}‘,0),split(time,’😂[0]))
select calTime(buytime) as time,sum(price) as sale from transaction_details group by calTime(buytime)

–define time bucket
–early morning: (5:00, 8:00]
–morning: (8:00, 11:00]
–noon: (11:00, 13:00]
–afternoon: (13:00, 18:00]
–evening: (18:00, 22:00]
–night: (22:00, 5:00] --make it as else, since it is not liner increasing
–We also format the time. 1st format time to 19:23 like, then compare, then convert minites to hours
with
t1 as
(select calTime(buytime) as time,sum(price) as sale from transaction_details group by calTime(buytime) order by time),
t2 as
(select if(time>5 and time<=8,‘early morning’,if(time >8 and time<=11,‘moring’,if(time>11 and time <13,‘noon’,
if(time>13 and time <=18,‘afternoon’,if(time >18 and time <=22,‘evening’,‘night’))))) as sumtime,sale
from t1)
select sumtime,sum(sale) from t2
group by sumtime

* 按工作日计算平均消费
select concat(‘星期’,dayofweek(regexp_replace(buydate,‘/’,‘-’))-1)
as week,avg(price) as sale from transaction_details
where dayofweek(regexp_replace(buydate,‘/’,‘-’))-1 !=0 and dayofweek(regexp_replace(buydate,‘/’,‘-’))-1 !=6
group by dayofweek(regexp_replace(buydate,‘/’,‘-’))

* 计算年、月、日的交易总数
select buydate as month,count(*) as salenum from transaction_details group by buydate
* 找出交易量最大的10个客户
select c.customer_id,c.first_name,c.last_name,count(c.customer_id) as custnum from customer_details c
inner join transaction_details t
on c.customer_id=t.customer_id
group by c.customer_id,c.first_name,c.last_name
order by custnum desc
limit 10
* 找出消费最多的前10位顾客
select c.customer_id,c.first_name,c.last_name,sum(price) as sumprice from customer_details c
inner join transaction_details t
on c.customer_id=t.customer_id
group by c.customer_id,c.first_name,c.last_name
order by sumprice desc
limit 10
* 统计该期间交易数量最少的用户
select c.customer_id,c.first_name,c.last_name,count(*) as custnum from customer_details c
inner join transaction_details t
on c.customer_id=t.customer_id
group by c.customer_id,c.first_name,c.last_name
order by custnum asc
limit 1
* 计算每个季度的独立客户总数
select calQuarter(buydate) as quarter,count(distinct customer_id) as uninum
from transaction_details
group by calQuarter(buydate)
* 计算每周的独立客户总数
select calWeek(buydate) as quarter,count(distinct customer_id) as uninum
from transaction_details
group by calWeek(buydate)
* 计算整个活动客户平均花费的最大值
select sum(price)/count(*) as sale
from transaction_details
group by customer_id
order by sale desc
limit 1
* 统计每月花费最多的客户
with
t1 as
(select customer_id,partday,count(distinct buydate) as visit from transaction_details group by partday,customer_id),
t2 as
(select customer_id,partday,visit,row_number() over(partition by partday order by visit desc) as visitnum from t1)
select * from t2 where visitnum=1
* 统计每月访问次数最多的客户
with
t1 as
(select customer_id,partday,sum(price) as pay from transaction_details group by partday,customer_id),
t2 as
(select customer_id,partday,pay,row_number() over(partition by partday order by pay desc) as paynum from t1)
select * from t2 where paynum=1
* 按总价找出最受欢迎的5种产品
select product,sum(price) as sale from transaction_details
group by product
order by sale desc
limit 5
* 根据购买频率找出最畅销的5种产品
select product,count(*) as num from transaction_details
group by product
order by num desc
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
t,sum(price) as sale from transaction_details
group by product
order by sale desc
limit 5
* 根据购买频率找出最畅销的5种产品
select product,count(*) as num from transaction_details
group by product
order by num desc
[外链图片转存中…(img-zm1dfOQK-1715698779624)]
[外链图片转存中…(img-pKwf0q2W-1715698779624)]
[外链图片转存中…(img-TRIuLmyx-1715698779624)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新