工具使用
kettle,Navicat,Tableau,xmind
数据集
理解数据(数据预处理后)
user_id | 用户ID |
item_id | 商品ID |
category_id | 商品类别ID |
behavior_type | 行为类型 pv:商品详情页pv,等价于点击 buy:商品购买 cart:将商品加入购物车 fav:收藏商品 |
timestamps | 时间戳 |
datetimes/dates/times/hours | 时间 |
导入一亿条数据
1.命令提示符
1.1在命令提示符中进入MySQL
1.2在MySQL中建立相应的数据库以及表
![](https://i-blog.csdnimg.cn/blog_migrate/804002ffc5db2da2b46d677835184b2d.png)
2.kettle
2.1新建转换——输入-CSV文件输入——输出-表输出
2.2打开CSV——浏览——选择数据集中的.CSV文件——取消"包含列头行"——获取字段——用命令提示符中的字段名称替换掉kettle中的名称并且修改字段的长度
![](https://i-blog.csdnimg.cn/blog_migrate/98c2b52c3b3ebbfc0a756fe46a96f1bb.png)
2.3打开表输出——新建数据库连接——选择MYSQL——填写连接名称(connect mysql)、主机名称(localhost),数据库名称(taobao),端口号、用户名、密码——点击测试
2.4打开连接池(表输出)——使用连接词——设置初始大小、最大空闲空间(皆为100)——将自动取消设置为false
2.5选项(表输出)——设置参数
![](https://i-blog.csdnimg.cn/blog_migrate/47e2ee40815a8d7179b1c24178f3ae2f.png)
2.6表输出——提交记录数量10000——勾选指定数据字段-点击获取字段
2.7主页将输入拖动到输出(主输入步骤)——表输出右键-改变开始复制的数量(10~20)
2.8表输出——浏览目标表——user_behavior——点击获取字段——填写数据库字段和字段流
![](https://i-blog.csdnimg.cn/blog_migrate/1cc74ca6efd3502e7c5aa17c006ff0e6.png)
2.9填写表输出的数据库字段中的流字段——运行-启动-命名
3.命令提示符(测试是否导入成功)
![](https://i-blog.csdnimg.cn/blog_migrate/774033655ca19282bf17b134142774fc.png)
数据预处理
定义:数据预处理是指根据需求增减字段或者值,主要有应用在字段名、字段类型、字段约束、值的去空、去重、去异常
1.navicat查询中进行预处理
![](https://i-blog.csdnimg.cn/blog_migrate/3e8219c6ee73ab734d4ed6181df2718e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a0a4e2812a1015918cbc8387fbf24ad4.png)
use taobao;
desc user_behavior;
-- desc 表名 查看表的结构
SELECT *
FROM user_behavior
LIMIT 5;
-- timestamp同数据类型的timestamp重名,需修改
/*
修改字段名
alter table 表名 change 旧字段名 新字段名 新数据类型
*/
ALTER TABLE user_behavior CHANGE timestamp timestamps int(14);
desc user_behavior;
-- 检查空值
SELECT *
FROM user_behavior
WHERE user_id IS NULL;
SELECT *
FROM user_behavior
WHERE item_id IS NULL;
SELECT *
FROM user_behavior
WHERE category_id IS NULL;
SELECT *
FROM user_behavior
WHERE behavior_type IS NULL;
SELECT *
FROM user_behavior
WHERE timestamps IS NULL;
-- 检查重复值(这里查询的是组合的重复值)
/*
重复值查询
select 检查的字段
from 表
group by 检查的字段
having count(检查字段)>1
*/
SELECT user_id,item_id,timestamps
FROM user_behavior
GROUP BY user_id,item_id,timestamps
HAVING COUNT(*)>1;
-- 去重
/*
添加一个字段并且居于首位
alter table 表名 add 字段名 字段类型 first
*/
ALTER TABLE user_behavior ADD id int FIRST;
SELECT *
FROM user_behavior
LIMIT 5;
/*
修改字段为主键并且自增
alter table 表名 modify 字段名 字段类型 primary key auto_increment
对已经存在的表,添加主键约束
alter table 表名 modify 字段名 字段类型 primary key
自增
auto_increment
*/
ALTER TABLE user_behavior MODIFY id INT PRIMARY KEY auto_increment;
/*
数据的去重
1 找到重复值,并命名
1.1 用group by 将字段组合起来,会将重复的值压缩为一条
1.2 用count(*)查找重复的数量
1.3 将重复的字段展现出来,并且找到重复值中最小的id号
1.4 将找到的重复值作为子查询命名
2 去重
2.1 用where筛选
2.2 子查询的字段和外查询的字段相同时删除数据,必须同时满足数据
2.3 user_behavior.id > t2.id (删除重复值的范围,只保留group by中他的最小id的数据)
delete 后直接跟表,是因为我只需要删除user_behavior的数据,而非t2的数据
*/
DELETE user_behavior
FROM user_behavior,
(
SELECT user_id,item_id,timestamps,MIN(id) id
FROM user_behavior
GROUP BY user_id,item_id,timestamps
HAVING COUNT(*)>1
) t2
WHERE user_behavior.user_id = t2.user_id
AND user_behavior.item_id = t2.item_id
AND user_behavior.timestamps = t2.timestamps
AND user_behavior.id > t2.id;
-- 新增字段:date time hour
-- 更改buffer值(更改缓冲值的大小)
-- 查看缓冲值现在的大小
/*
查看缓冲池,并对他进行修改
1 show variables 查看系统变量及其值
2 like模糊查询
3 set global 全局变量的设置,后面跟赋值公式
*/
SHOW VARIABLES LIKE '%_buffer%';
-- 设缓冲值为10G
SET GLOBAL innodb_buffer_pool_size = 10700000000;
-- TIMESTAMP(0) 0的意思是秒后面的位数为0
-- 添加一个时间字段,并且秒后面的位数为0
ALTER TABLE user_behavior ADD datetimes TIMESTAMP(0);
-- int型的TIMESTAMP改为日期型的TIMESTAMP(天啦,运行了5个小时,我要减少一下数据量了)
/*
将int型的TIMESTAMP改为日期型的TIMESTAMP
1 更新已有数据
update 表名 set 字段=值
2 int的时间戳修改为日期型
from_unixtime(时间戳)
*/
UPDATE user_behavior SET datetimes = FROM_UNIXTIME(timestamps);
-- 数据过多删除某些行,只保留50w数据(难以运行)
DELETE FROM user_behavior
WHERE id > 500000;
-- 插入dates、times、hours
-- 添加 日期、时间、小时的字段,并设置数据类型和长度
ALTER TABLE user_behavior ADD dates char(10);
ALTER TABLE user_behavior ADD times char(8);
ALTER TABLE user_behavior ADD hours char(2);
/* SUBSTRING(str,start, length):str:代表字符串,start:代表是从第几位开始截取,length:代表截取几位数
*/
UPDATE user_behavior set dates = SUBSTRING(datetimes,1,10),
times = SUBSTRING(datetimes,12,8),
hours = SUBSTRING(datetimes,12,2);
-- 去异常——时间范围的异常(2017.11.25-12.3)
SELECT MAX(datetimes),MIN(datetimes)
FROM user_behavior;
-- 异常的去除方法
DELETE FROM user_behavior
WHERE datetimes < "2017-11-25 00:00:00"
OR datetimes > "2017-12-03 23:59:59";
-- 数据概览
DESC user_behavior;
SELECT *
FROM user_behavior
LIMIT 5;
SELECT COUNT(*) FROM user_behavior; #499779条数据
获客情况
![](https://i-blog.csdnimg.cn/blog_migrate/268a8925ea4c2a9e693abe756f2555e0.png)
-- 创建临时表,临时表的字段名和原表相同,但是无数据
/*
创建临时表格,并复制原表的字段名,不复制数据
create table 临时表名 like 原表
*/
CREATE TABLE temp_behavior
LIKE user_behavior;
-- 截取原表中的100000条数据插入临时表中
/*
截取原表的数据插入临时表中
insert into 临时表 select 列 from 表 limit 数据量
*/
INSERT INTO temp_behavior
SELECT *
FROM user_behavior
LIMIT 100000;
-- 查看临时表数据
SELECT *
FROM temp_behavior;
-- PV 页面浏览量 每天页面的点击数
SELECT dates,COUNT(*) "pv"
FROM temp_behavior
WHERE behavior_type = "pv"
GROUP BY dates
ORDER BY dates;
-- UV 独立的访客数(当日的客户数量) 去除每天相同客户的点击
SELECT dates,COUNT(DISTINCT user_id) "uv"
FROM temp_behavior
WHERE behavior_type = "pv"
GROUP BY dates
ORDER BY dates;
-- uv、pv每天顾客浏览了多少次
/*
round(a,b)
a:要处理的数
b:保留几位小数
*/
SELECT dates,
COUNT(*) "pv",
COUNT(DISTINCT user_id) "uv",
ROUND(COUNT(*)/COUNT(DISTINCT user_id),1) "pv/uv"
FROM temp_behavior
WHERE behavior_type = "pv"
GROUP BY dates
ORDER BY dates;
-- 创建获客情况表格
/*
创建表格并定义字段
create table 表名(字段1 字段类型1 ,字段2 字段类型2)
decimal型(十进制小数型)比float和double计算精度高,使用空间少,常用于金融运算。
1 浮点型会四舍五入,decimal则不会
2 decimal(a,b)
a:一共保留几位数
b:小数点后保留几位数
*/
CREATE TABLE pv_uv_puv(
dates char(10),
pv int(9),
uv int(9),
puv decimal(10,1)
);
-- 取原表中的数据插入获客情况表
/*
round(a,b)
a:要处理的数
b:保留几位小数
*/
INSERT INTO pv_uv_puv
SELECT dates,
COUNT(*) "pv",
COUNT(DISTINCT user_id) "uv",
ROUND(COUNT(*)/COUNT(DISTINCT user_id),1) "pv/uv"
FROM user_behavior
WHERE behavior_type = "pv"
GROUP BY dates
ORDER BY dates;
-- 查看获客情况表
SELECT *
FROM pv_uv_puv
ORDER BY dates;
-- *本次获客情况表无空值,若出现空值,可使用以下办法
DELETE FROM pv_uv_puv WHERE dates IS NULL;
留存情况
![](https://i-blog.csdnimg.cn/blog_migrate/251cedaf02bc257726d333ee3e62f88b.png)
SELECT * FROM user_behavior WHERE dates IS NULL;
SELECT *
FROM temp_behavior;
-- 留存率:活跃用户留存率,计算次日留存率
-- 用户活跃日期
SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates
ORDER BY user_id;
-- 自关联(隐式连接)
SELECT * FROM
(SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates
) a
,(SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates)
b
WHERE a.user_id=b.user_id;
-- 筛选
SELECT * FROM
(SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates
) a
,(SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates)
b
WHERE a.user_id=b.user_id AND a.dates < b.dates;
--datediff函数返回两个日期之间的天数,对时间差值的计算方式为date1-date2的差值。
-- 留存数,以日期为单位的顾客数量
SELECT a.dates,
COUNT(if(datediff(b.dates,a.dates)=0,b.user_id,NULL)) rentention0,
COUNT(if(datediff(b.dates,a.dates)=1,b.user_id,NULL)) rentention1
FROM
(SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates
) a
,(SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates)
b
WHERE a.user_id=b.user_id AND a.dates <= b.dates
GROUP BY a.dates
-- 留存率
SELECT a.dates,
COUNT(if(datediff(b.dates,a.dates)=1,b.user_id,NULL))/COUNT(if(datediff(b.dates,a.dates)=0,b.user_id,NULL)) rentention1
FROM
(SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates
) a
,(SELECT user_id,dates
FROM temp_behavior
GROUP BY user_id,dates)
b
WHERE a.user_id=b.user_id AND a.dates <= b.dates
GROUP BY a.dates
-- 保存结果
CREATE TABLE retention_rate
(
dates CHAR(10),
retention_1 FLOAT);
INSERT INTO retention_rate
SELECT a.dates,
COUNT(if(datediff(b.dates,a.dates)=1,b.user_id,NULL))/COUNT(if(datediff(b.dates,a.dates)=0,b.user_id,NULL)) rentention1
FROM
(SELECT user_id,dates
FROM user_behavior
GROUP BY user_id,dates
) a
,(SELECT user_id,dates
FROM user_behavior
GROUP BY user_id,dates)
b
WHERE a.user_id=b.user_id AND a.dates <= b.dates
GROUP BY a.dates;
SELECT *
FROM retention_rate
-- 跳失率,是指显示顾客通过相应入口进入,只访问了一个页面就离开的访问次数占该页面总访问次数的比例。
-- 跳失用户
-- 10
SELECT count(*)
FROM
(
SELECT user_id
FROM user_behavior
GROUP BY user_id
HAVING COUNT(behavior_type) = 1
) a
-- 448998
SELECT SUM(pv) FROM pv_uv_puv
-- 10/448998
时间序列分析
![](https://i-blog.csdnimg.cn/blog_migrate/7964bf9a4b93f448e7dd18d9745c39f3.png)
1.在sql中创建date_hour_behavior
--统计日期一小时行为
SELECT dates,hours,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) 'pv',
COUNT(IF(behavior_type = 'cart',behavior_type,NULL)) 'cart',
COUNT(IF(behavior_type = 'fav',behavior_type,NULL)) 'fav',
COUNT(IF(behavior_type = 'buy',behavior_type,NULL)) 'buy'
FROM temp_behavior
GROUP BY dates,hours
ORDER BY dates,hours
-- 存储
CREATE TABLE date_hour_behavior AS
(SELECT dates,hours,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) 'pv',
COUNT(IF(behavior_type = 'cart',behavior_type,NULL)) 'cart',
COUNT(IF(behavior_type = 'fav',behavior_type,NULL)) 'fav',
COUNT(IF(behavior_type = 'buy',behavior_type,NULL)) 'buy'
FROM user_behavior
GROUP BY dates,hours
ORDER BY dates,hours)
-- 检查
SELECT * FROM date_hour_behavior
2.tableau
2.1 分析用户的周内行为
11月25日、26日,12月2日、3日是周末,用户在周末的各种行为均高于工作日
![](https://i-blog.csdnimg.cn/blog_migrate/07e8bff860a4878d2787bc6cbe3016a6.png)
2.2 分析用户的小时行为
![](https://i-blog.csdnimg.cn/blog_migrate/b23928c051b264ededd74aa092c04fbf.png)
2.3 共同分析用户的周内行为和小时行为
![](https://i-blog.csdnimg.cn/blog_migrate/21c5965533875629d6b4c2d2aa8b4b11.png)
2.4 分析用户下单购买的概率
![](https://i-blog.csdnimg.cn/blog_migrate/d0a5314ad98692bc1e48390bb245649a.png)
用户转化率分析
![](https://i-blog.csdnimg.cn/blog_migrate/1c13f2c59eb1787ad723cc86c0a4465f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bdce7f9b93c217543010bf4e5cfa2ed2.png)
-- 统计各类行为用户数
SELECT behavior_type,
COUNT(DISTINCT user_id) use_num
FROM temp_behavior
GROUP BY behavior_type
ORDER BY behavior_type DESC
-- 存储
CREATE TABLE behavior_user_num AS
SELECT behavior_type,
COUNT(DISTINCT user_id) use_num
FROM user_behavior
GROUP BY behavior_type
ORDER BY behavior_type DESC
SELECT * FROM behavior_user_num
-- 0.6631(购买概率)
SELECT 3444/5194
-- 统计各类行为的数量
SELECT behavior_type,
COUNT(*) behavior_count_num
FROM temp_behavior
GROUP BY behavior_type
ORDER BY behavior_type DESC
-- 储存数据
CREATE TABLE behavior_num AS
SELECT behavior_type,
COUNT(*) behavior_count_num
FROM user_behavior
GROUP BY behavior_type
ORDER BY behavior_type DESC
SELECT * FROM behavior_num
-- buy/pv 0.0228
SELECT 10226/448998
-- (fav+cart)/pv 0.0903
SELECT (13013+27542)/448998
行为路径分析
-- 删除后面使用temp_behavior创建的视图,并使用原表进行视图的再次创建
DROP VIEW user_behavior_view
DROP VIEW user_behavior_standard
DROP VIEW user_behavior_path
DROP VIEW path_count
-- 在查询中对字段内的内容进行筛选可用if
-- 用户对商品行为类型的计算
CREATE VIEW user_behavior_view AS
SELECT user_id,item_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) pv,
COUNT(IF(behavior_type = 'cart',behavior_type,NULL)) cart,
COUNT(IF(behavior_type = 'fav',behavior_type,NULL)) fav,
COUNT(IF(behavior_type = 'buy',behavior_type,NULL)) buy
FROM temp_behavior
GROUP BY user_id,item_id
-- 用户行为标准化
CREATE VIEW user_behavior_standard AS
SELECT user_id,item_id,
(CASE WHEN pv>0 THEN 1 ELSE 0 END) '浏览了',
(CASE WHEN fav>0 THEN 1 ELSE 0 END) '收藏了',
(CASE WHEN cart>0 THEN 1 ELSE 0 END) '加购了',
(CASE WHEN buy>0 THEN 1 ELSE 0 END) '购买了'
FROM user_behavior_view
-- 购买路径类型
-- CONCAT拼接函数
CREATE VIEW user_behavior_path AS
SELECT *,
CONCAT(浏览了,收藏了,加购了,购买了) 购买路径类型
FROM user_behavior_standard AS a
WHERE a.购买了> 0
-- 统计各类购买行为数量
CREATE VIEW path_count AS
SELECT 购买路径类型,count(*) 数量
FROM user_behavior_path
GROUP BY 购买路径类型
ORDER BY 数量 DESC
-- 解释表
CREATE TABLE explanation(
path_type char(4),
description VARCHAR(40)
)
INSERT INTO explanation
VALUES('0001','直接购买'),
('1001','浏览后购买'),
('0011','加购后购买'),
('1011','浏览加购后购买'),
('0101','收藏后购买'),
('1101','浏览收藏后购买'),
('0111','收藏加购后购买'),
('1111','浏览收藏加购后购买')
SELECT * FROM explanation
SELECT * FROM explanation e
JOIN path_count pc
ON pc.购买路径类型 = e.path_type
ORDER BY 数量 DESC
-- 使用原始表
-- 在查询中对字段内的内容进行筛选可用if
CREATE VIEW user_behavior_view AS
SELECT user_id,item_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) pv,
COUNT(IF(behavior_type = 'cart',behavior_type,NULL)) cart,
COUNT(IF(behavior_type = 'fav',behavior_type,NULL)) fav,
COUNT(IF(behavior_type = 'buy',behavior_type,NULL)) buy
FROM user_behavior
GROUP BY user_id,item_id
-- 用户行为标准化
CREATE VIEW user_behavior_standard AS
SELECT user_id,item_id,
(CASE WHEN pv>0 THEN 1 ELSE 0 END) '浏览了',
(CASE WHEN fav>0 THEN 1 ELSE 0 END) '收藏了',
(CASE WHEN cart>0 THEN 1 ELSE 0 END) '加购了',
(CASE WHEN buy>0 THEN 1 ELSE 0 END) '购买了'
FROM user_behavior_view
-- 路径类型
CREATE VIEW user_behavior_path AS
SELECT *,
CONCAT(浏览了,收藏了,加购了,购买了) 购买路径类型
FROM user_behavior_standard AS a
WHERE a.购买了> 0
-- 统计各类购买行为数量
CREATE VIEW path_count AS
SELECT 购买路径类型,count(*) 数量
FROM user_behavior_path
GROUP BY 购买路径类型
ORDER BY 数量 DESC
-- 解释表
CREATE TABLE explanation(
path_type char(4),
description VARCHAR(40)
)
INSERT INTO explanation
VALUES('0001','直接购买'),
('1001','浏览后购买'),
('0011','加购后购买'),
('1011','浏览加购后购买'),
('0101','收藏后购买'),
('1101','浏览收藏后购买'),
('0111','收藏加购后购买'),
('1111','浏览收藏加购后购买')
SELECT * FROM explanation
SELECT * FROM explanation e
JOIN path_count pc
ON pc.购买路径类型 = e.path_type
ORDER BY 数量 DESC
CREATE TABLE path_result AS
SELECT path_type,description,数量
FROM explanation e
JOIN path_count pc
ON pc.购买路径类型 = e.path_type
ORDER BY 数量 DESC
SELECT *
FROM path_result
-- 购买但没有收藏加购的购买数量 7785
SELECT sum(buy)
FROM user_behavior_view
WHERE buy>0 AND fav=0 AND cart=0
-- 总购买量 10226
-- 收藏加购后购买量 2441
-- 收藏加购 13013+27542
-- 收藏加购后购买的概率 0.0602
SELECT 2441/(13013+27542)
RFM模型
![](https://i-blog.csdnimg.cn/blog_migrate/ce052e3035c533b08e679934cf0084ff.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b45495bd8605e82bd9c9cefc019df511.png)
-- 最近购买的时间
SELECT user_id,MAX(dates) '最近购买时间'
FROM user_behavior
WHERE behavior_type = "buy"
GROUP BY user_id
ORDER BY 2 DESC;
#ORDER BY后面的数字分别代表SELECT后面的第几个字段,当查询的列发生改变,容易忘记修改ORDER BY列表。
-- 购买次数
SELECT user_id,count(user_id) "购买次数"
FROM user_behavior
WHERE behavior_type = "buy"
GROUP BY user_id
ORDER BY 2 DESC;
-- 统一
SELECT user_id,count(user_id) "购买次数",MAX(dates) "最近购买时间"
FROM user_behavior
WHERE behavior_type = "buy"
GROUP BY user_id
ORDER BY 2 DESC,3 DESC;
-- 创建表之前判断表是否存在,如果存在则删除已有表
-- DROP table IF EXISTS rfm_model
-- 储存
CREATE TABLE RFM_model AS
SELECT user_id,count(user_id) "购买次数",MAX(dates) "最近购买时间"
FROM user_behavior
WHERE behavior_type = "buy"
GROUP BY user_id
ORDER BY 2 DESC,3 DESC;
-- 根据购买的次数对用户进行分层
ALTER TABLE rfm_model ADD fscore int;
UPDATE rfm_model
SET fscore = CASE
WHEN 购买次数 BETWEEN 50 AND 60 THEN 5
WHEN 购买次数 BETWEEN 40 AND 59 THEN 4
WHEN 购买次数 BETWEEN 25 AND 39 THEN 3
WHEN 购买次数 BETWEEN 15 AND 24 THEN 2
ELSE 1
END
SELECT * FROM rfm_model
-- 根据最近购买时间对用户进行分层
ALTER TABLE rfm_model ADD rscore INT;
UPDATE rfm_model
SET rscore = CASE
WHEN 最近购买时间 = '2017-12-03' THEN 5
WHEN 最近购买时间 IN ('2017-12-01','2017-12-02') THEN 4
WHEN 最近购买时间 IN ('2017-11-29','2017-11-30') THEN 3
WHEN 最近购买时间 IN ('2017-11-27','2017-11-28') THEN 2
ELSE 1
END
-- 定义两个变量,存取f和r的平均值
SET @r_avg = NULL;
SET @f_avg = NULL;
SELECT AVG(fscore) INTO @f_avg FROM rfm_model;
SELECT AVG(rscore) INTO @r_avg FROM rfm_model;
-- 根据平均数将用户分类
SELECT *,
(CASE
WHEN fscore>@f_avg AND rscore>@r_avg THEN '价值用户'
WHEN fscore>@f_avg AND rscore<@r_avg THEN '保持用户'
WHEN fscore<@f_avg AND rscore>@r_avg THEN '发展用户'
WHEN fscore<@f_avg AND rscore<@r_avg THEN '挽留用户'
END) class
FROM rfm_model
-- 插入
-- COLUMN关键字是可选的,因此您可以省略它。
ALTER TABLE rfm_model ADD COLUMN class VARCHAR(40);
UPDATE rfm_model
SET class = CASE
WHEN fscore>@f_avg AND rscore>@r_avg THEN '价值用户'
WHEN fscore>@f_avg AND rscore<@r_avg THEN '保持用户'
WHEN fscore<@f_avg AND rscore>@r_avg THEN '发展用户'
WHEN fscore<@f_avg AND rscore<@r_avg THEN '挽留用户'
END
-- 统计各分区的用户数
SELECT class,COUNT(user_id)
FROM rfm_model
GROUP BY class
商品按照热度分类
![](https://i-blog.csdnimg.cn/blog_migrate/eec127ca15372b7431c0dfbb5c96fa21.png)
-- 商品类别浏览量排名
SELECT category_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) '品类浏览量'
FROM user_behavior u
GROUP BY u.category_id
ORDER BY 2 DESC
LIMIT 10
-- 商品浏览量排名
SELECT item_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) '商品浏览量'
FROM user_behavior u
GROUP BY item_id
ORDER BY 2 DESC
LIMIT 10
-- 品类中商品的浏览量排名
SELECT category_id,item_id,品类中的商品浏览量
FROM
(
SELECT item_id,
category_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) '品类中的商品浏览量',
RANK()over(PARTITION by category_id ORDER BY COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) DESC ) r
FROM user_behavior u
GROUP BY category_id,item_id
ORDER BY 3 DESC
) a
WHERE a.r = 1
ORDER BY a.品类中的商品浏览量 DESC
LIMIT 10
CREATE TABLE popular_categories(
category_id INT,
pv INT
);
CREATE TABLE popular_items(
item_id INT,
pv INT
);
CREATE TABLE popular_cateitems(
category_id INT,
item_id INT,
pv INT
)
INSERT INTO popular_categories
SELECT category_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) '品类浏览量'
FROM user_behavior u
GROUP BY u.category_id
ORDER BY 2 DESC
LIMIT 10;
INSERT INTO popular_items
SELECT item_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) '商品浏览量'
FROM user_behavior u
GROUP BY item_id
ORDER BY 2 DESC
LIMIT 10;
INSERT INTO popular_cateitems
SELECT category_id,item_id,品类中的商品浏览量
FROM
(
SELECT item_id,
category_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) '品类中的商品浏览量',
RANK()over(PARTITION by category_id ORDER BY COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) DESC ) r
FROM user_behavior u
GROUP BY category_id,item_id
ORDER BY 3 DESC
) a
WHERE a.r = 1
ORDER BY a.品类中的商品浏览量 DESC
LIMIT 10;
SELECT * FROM popular_categories
商品转化率分析
![](https://i-blog.csdnimg.cn/blog_migrate/da73964fc3083c05ed0dcfaf04a33213.png)
-- 特点商品转化率
SELECT item_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) pv,
COUNT(IF(behavior_type = 'cart',behavior_type,NULL)) cart,
COUNT(IF(behavior_type = 'fav',behavior_type,NULL)) fav,
COUNT(IF(behavior_type = 'buy',behavior_type,NULL)) buy,
COUNT(DISTINCT IF(behavior_type = 'buy',user_id,NULL)) / COUNT(DISTINCT user_id) '商品转化率'
FROM user_behavior
GROUP BY item_id
ORDER BY 商品转化率 DESC
-- 保存
CREATE TABLE item_detail(
item_id INT,
pv INT,
fav INT,
cart INT,
buy INT,
user_buy_rate FLOAT
);
INSERT INTO item_detail
SELECT item_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) pv,
COUNT(IF(behavior_type = 'cart',behavior_type,NULL)) cart,
COUNT(IF(behavior_type = 'fav',behavior_type,NULL)) fav,
COUNT(IF(behavior_type = 'buy',behavior_type,NULL)) buy,
COUNT(DISTINCT IF(behavior_type = 'buy',user_id,NULL)) / COUNT(DISTINCT user_id) '商品转化率'
FROM user_behavior
GROUP BY item_id
ORDER BY 商品转化率 DESC;
SELECT * FROM item_detail;
-- 品类转化率
CREATE TABLE category_detail(
category_id INT,
pv INT,
fav INT,
cart INT,
buy INT,
user_buy_rate FLOAT
);
INSERT INTO category_detail
SELECT category_id,
COUNT(IF(behavior_type = 'pv',behavior_type,NULL)) pv,
COUNT(IF(behavior_type = 'cart',behavior_type,NULL)) cart,
COUNT(IF(behavior_type = 'fav',behavior_type,NULL)) fav,
COUNT(IF(behavior_type = 'buy',behavior_type,NULL)) buy,
COUNT(DISTINCT IF(behavior_type = 'buy',user_id,NULL)) / COUNT(DISTINCT user_id) '品类转化率'
FROM user_behavior
GROUP BY category_id
ORDER BY 品类转化率 DESC;
SELECT * FROM category_detail;
商品特征分析(Tableau)
![](https://i-blog.csdnimg.cn/blog_migrate/c2c34f9f7b8f3cfe5e0eabc360b75ba3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/993fbe6c4bd31e7e67165b5d561d3659.png)
![](https://i-blog.csdnimg.cn/blog_migrate/da1ca02d46e38584cd8307d56fd44979.png)
![](https://i-blog.csdnimg.cn/blog_migrate/86c6357d28ee13b95e056c37352fe3ef.png)
点击数高、购买数高 = 刚需产品
点击数少、购买数少 = 存在替代品,客户很难在一个产品大量购买
点击数高、购买数少 = 商品需求弹性较大
注:基于项目的SQL知识点
1.修改字段名
alter table 表名 change 旧字段名 新字段名 新数据类型
举例:
ALTER TABLE user_behavior CHANGE timestamp timestamps int(14);
2.重复值查询
select 检查的字段
from 表
group by 检查的字段
having count(检查字段)>1
举例:
SELECT user_id,item_id,timestamps
FROM user_behavior
GROUP BY user_id,item_id,timestamps
HAVING COUNT(*)>1;
3.添加一个字段
3.1 添加一个字段并且居于首位
alter table 表名 add 字段名 字段类型 first
ALTER TABLE user_behavior ADD id int FIRST;
3.2 添加一个时间字段,并秒后面的位数为0
ALTER TABLE user_behavior ADD datetimes TIMESTAMP(0);
3.3 添加 日期、时间、小时的字段,并设置数据类型和长度
ALTER TABLE user_behavior ADD dates char(10);
ALTER TABLE user_behavior ADD times char(8);
ALTER TABLE user_behavior ADD hours char(2);
4.修改字段为主键并且自增
alter table 表名 modify 字段名 字段类型 primary key auto_increment
4.1 对已经存在的表,添加主键约束
alter table 表名 modify 字段名 字段类型 primary key
4.2自增
auto_increment
举例:
ALTER TABLE user_behavior MODIFY id INT PRIMARY KEY auto_increment;
5.数据的去重
5.1 找到重复值,并命名
5.1.1 用group by 将字段组合起来,会将重复的值压缩为一条
5.1.2 用count(*)查找重复的数量
5.1.3 将重复的字段展现出来,并且找到重复值中最小的id号
5.1.4 将找到的重复值作为子查询命名
5.2 去重
5.2.1 用where筛选
5.2.2 子查询的字段和外查询的字段相同时删除数据,必须同时满足数据
5.2.3 user_behavior.id > t2.id (删除重复值的范围,只保留group by中他的最小id的数据)
注意:delete from后跟子查询,就不应使用DELETE FROM 表,而应该DELETE 表 FROM 表,
DELETE user_behavior FROM user_behavior,
(
SELECT user_id,item_id,timestamps,MIN(id) id
FROM user_behavior
GROUP BY user_id,item_id,timestamps
HAVING COUNT(*)>1
) t2
WHERE user_behavior.user_id = t2.user_id
AND user_behavior.item_id = t2.item_id
AND user_behavior.timestamps = t2.timestamps
AND user_behavior.id > t2.id;
6.查看缓冲池,并对他进行修改
6.1 show variables 查看系统变量及其值
6.2 like模糊查询
6.3 set global 全局变量的设置,后面跟赋值公式
SHOW VARIABLES LIKE '%_buffer%';
SET GLOBAL innodb_buffer_pool_size = 10700000000;
7.将int型的TIMESTAMP改为日期型的TIMESTAMP
7.1 更新已有数据
update 表名 set 字段=值
7.2 int的时间戳修改为日期型
from_unixtime(时间戳)
UPDATE user_behavior SET datetimes = FROM_UNIXTIME(timestamps);
8.截取子串并补充日期、时间、小时的数据
8.1 截取子串
SUBSTRING(str,start, length)
str:代表字符串,start:代表是从第几位开始截取,length:代表截取几位数
UPDATE user_behavior
SET dates = SUBSTRING(datetimes,1,10),
times = SUBSTRING(datetimes,12,8),
hours = SUBSTRING(datetimes,12,2);
9.创建临时表格,并复制原表的字段名,不复制数据
create table 临时表名 like 原表
CREATE TABLE temp_behavior LIKE user_behavior;
10.截取原表的数据插入临时表中
insert into 临时表 select 列 from 表 limit 数据量
INSERT INTO temp_behavior SELECT * FROM user_behavior LIMIT 100000;
11.项目中pv,uv查看
SELECT dates,
COUNT(*) "pv",
COUNT(DISTINCT user_id) "uv",
ROUND(COUNT(*)/COUNT(DISTINCT user_id),1) "pv/uv"
FROM temp_behavior
WHERE behavior_type = "pv"
GROUP BY dates
ORDER BY dates;
11.1 round(a,b)
a:要处理的数
b:保留几位小数
12.创建表格并定义字段
create table 表名(字段1 字段类型1 ,字段2 字段类型2)
CREATE TABLE pv_uv_puv(
dates char(10),
pv int(9),
uv int(9),
puv decimal(10,1)
);
12.1 decimal型(十进制小数型)比float和double计算精度高,使用空间少,常用于金融运算。
12.1.1 浮点型会四舍五入,decimal则不会
12.1.2 decimal(a,b)
a:一共保留几位数
b:小数点后保留几位数