我去查了一下订单表,需要案例数据的,关注并进入公众号后,回复“数据源”,商品运营案例表数据。
SELECT
user_type,
order_products
FROM
`商品运营案例`
WHERE
DATE_FORMAT(order_time,"%Y/%m")="2020/08";复制
这是什么鬼,原来生产环境中order_products记录的是:产品编码(销量);产品编码(销量);...,那就是要把每单的产品和销量差分开来,然后再汇总。
先看怎么拆分产品和数量吧
有那么一个函数叫SUBSTRING_INDEX()
语法:substring_index("待截取有用部分的字符串","截取数据依据的字符",截取依据的字符的位置N[正常从前往后,若为-1则是从后往前截取依据的字符后面的内容])
有一个mysql的存放参考文档的表mysql.help_topic
select * from mysql.help_topic
拆分产品思路
按照分号拆分,有多少个分号呢,(length(a.order_products)-length(REPLACE(a.order_products,';',''))) ,即总长度-去除分号的长度。 每个分号都要拆分一次,也就是位置1拆分1次,位置2拆分1次,...,
SELECT
a.user_type as 客户类型,
a.order_products as 订单产品,
b.help_topic_id+1,
SUBSTRING_INDEX(a.order_products, ';', b.help_topic_id+1)
FROM
商品运营案例 AS a
JOIN
mysql.help_topic AS b
ON
b.help_topic_id<(length(a.order_products)-length(REPLACE(a.order_products,';','')))
WHERE
DATE_FORMAT(order_time,"%Y/%m")="2020/08"复制
结果如上,为什么两个分号有6个结果呢,其实我们的一个中文状态下的分号长度是3导致。
截取每个分号的最后一个产品编号和数量,这样每行就只有唯一不重复的一个产品编号和数量了,当然还有就是最后一个字符是分号的怎会产生空值,所以where条件中应该去除这部分。
SELECT
a.user_type as 客户类型,
a.order_products as 订单产品,
b.help_topic_id+1,
SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1) AS 产品编号_num
FROM
商品运营案例 AS a
JOIN
mysql.help_topic AS b
ON
b.help_topic_id<(length(a.order_products)-length(REPLACE(a.order_products,';','')))
WHERE
DATE_FORMAT(order_time,"%Y/%m")="2020/08"
AND
SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1)<>""复制
4. 接下来就是要把小括号中的产品和数量差分为两列。其中产品编号我们再来一次SUBSTRING_INDEX(产品编号_num,"(",1);产品数量等于replace(SUBSTRING_INDEX(产品编号_num,"(",-1),")","")
拆分产品的完整代码如下
SELECT
a.user_type as 客户类型,
a.order_products as 订单产品,
-- b.help_topic_id+1,
SUBSTRING_INDEX(
SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1)
,';',-1) AS 产品编号_num,
SUBSTRING_INDEX(
SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1)
,"(",1) AS 产品编号,
replace(
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1),"(",-1)
,")","") AS 产品数量
FROM
商品运营案例 AS a
JOIN
mysql.help_topic AS b
ON
b.help_topic_id<(length(a.order_products)-length(REPLACE(a.order_products,';','')))
WHERE
SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1)<>""
AND
DATE_FORMAT(order_time,"%Y/%m")="2020/08"复制

接下来就是分类汇总
需求:帮我查一下新客户和老客户分别在8月份买了多少A-J产品
SELECT
T1.客户类型,
COUNT(产品编号) AS 订单数,
SUM(产品数量) AS 产品数量
FROM
(
SELECT
a.user_type as 客户类型,
a.order_products as 订单产品,
-- b.help_topic_id+1,
SUBSTRING_INDEX(
SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1)
,';',-1) AS 产品编号_num,
SUBSTRING_INDEX(
SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1)
,"(",1) AS 产品编号,
replace(
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1),"(",-1)
,")","") AS 产品数量
FROM
商品运营案例 AS a
JOIN
mysql.help_topic AS b
ON
b.help_topic_id<(length(a.order_products)-length(REPLACE(a.order_products,';','')))
WHERE
SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1)<>""
AND
DATE_FORMAT(order_time,"%Y/%m")="2020/08"
AND
SUBSTRING_INDEX(
SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_products, ';',b.help_topic_id+1),';',-1)
,"(",1) = "A-J"
) AS T1
GROUP BY
T1.客户类型复制



文章转载自数据运营与数据分析,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【MySQL 30周年庆】MySQL 8.0 OCP考试限时免费!教你免费领考券
墨天轮小教习
3191次阅读
2025-04-25 18:53:11
MySQL 30 周年庆!MySQL 8.4 认证免费考!这次是认真的。。。
严少安
887次阅读
2025-04-25 15:30:58
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
527次阅读
2025-04-17 17:02:24
MySQL 9.3 正式 GA,我却大失所望,新特性亮点与隐忧并存?
JiekeXu
454次阅读
2025-04-15 23:49:58
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
382次阅读
2025-04-15 14:48:05
MySQL 8.0 OCP 1Z0-908 考试解析指南(二)
JiekeXu
340次阅读
2025-04-30 17:37:37
记录MySQL数据库的一些奇怪的迁移需求!
陈举超
301次阅读
2025-04-15 15:27:53
SQL优化 - explain查看SQL执行计划(下)
金同学
293次阅读
2025-05-06 14:40:00
MySQL 30 周年庆!MySQL 8.4 认证免费考!这次是认真的。。。
数据库运维之道
284次阅读
2025-04-28 11:01:25
MySQL 8.0 OCP 1Z0-908 考试题解析指南
青年数据库学习互助会
282次阅读
2025-04-30 12:17:54