不用ROLLUP,MySQL5.7完美运行的解法

某店铺的各商品毛利率及店铺整体毛利率

http://www.nowcoder.com/practice/65de67f666414c0e8f9a34c08d4a8ba6

题意

给你一张产品信息表,一张订单明细表,一张订单总表,请你查询出901店铺2021年10月份以来所有毛利率大于24.9%的商品信息和店铺的整体毛利率

思路

  • 既然需要商品和店铺两种,那么我们直接将问题分为两个部分不就行了?所以我们可以先行查询店铺的整体毛利率
  • 因为店铺毛利率 = (1 - 总进价成本 / 总销售成本) * 100%,所以我们应该求出卖出的商品进价总和以及销售总和(两者对应的商品数量应该一致),而最终结果的"%"符号则只需要使用CONCAT进行连接即可,所以SQL如下

SQL1

SELECT
	'店铺汇总' AS 'product_id',
	CONCAT(ROUND(100 * (1 - (SUM(t1.in_price * t2.cnt) / SUM(t2.price * t2.cnt))), 1), '%') AS 'profit_rate'
FROM
	tb_product_info AS t1
INNER JOIN tb_order_detail AS t2 ON t1.product_id = t2.product_id
INNER JOIN tb_order_overall AS t3 ON t2.order_id = t3.order_id
WHERE t1.shop_id = 901
AND DATE(t3.event_time) >= '2021-10-01'
  • 剩下的就是单个商品了,我们采用类似的方法即可,注意这里的毛利率需要基于单价计算
  • 问题是,在获取901店铺每个商品的毛利率后,怎么筛选出毛利率大于24.9%的呢?此时我们的SQL为

SQL2

SELECT
	t1.product_id,
	CONCAT(ROUND(100 * (1 - t1.in_price / AVG(t2.price)), 1), '%') AS 'profit_rate'
FROM
	tb_product_info AS t1
INNER JOIN tb_order_detail AS t2 ON t1.product_id = t2.product_id
INNER JOIN tb_order_overall AS t3 ON t2.order_id = t3.order_id
WHERE t1.shop_id = 901
AND DATE(t3.event_time) >= '2021-10-01'
GROUP BY t1.product_id
  • 直接在HAVING中使用profit_rate吗?profit_rate是CONCAT连接后的结果,它是一个字符串呀,不能与数字直接比较,那咋办?类型转换?但它还带有一个"%"呀
  • 不怕,我们可以先使用SUBSTRING_INDEX分割出数字部分,再使用CAST将其转换为DECIMAL类型即可,最终SQL如下
SQL1
UNION ALL
SQL2
HAVING CAST(SUBSTRING_INDEX(profit_rate, '%', 1) AS DECIMAL(3, 1)) > 24.9
  • 其他题解中用到了ROLLUP,在MySQL8.0确实没问题,但在MySQL5.7中ROLLUP和ORDER BY不能一起使用,因此我这里并未选择ROLLUP

     

官方文档

alt alt

MySQL练习 文章被收录于专栏

解析牛客网中的SQL题目

全部评论
你SQL2对吗?group by 不应该是这个把
点赞 回复 分享
发布于 2022-03-16 15:18
对avg理解不到位
点赞 回复 分享
发布于 2022-12-05 12:49 河南

相关推荐

喜欢走神的孤勇者练习时长两年半:爱华,信华,等华,黑华
点赞 评论 收藏
分享
无敌虾孝子:喜欢爸爸还是喜欢妈妈
点赞 评论 收藏
分享
17 1 评论
分享
牛客网
牛客企业服务