解题思路整理
1.组宽表
2.需求字段拆解:含义,计算逻辑,涉及字段,整理等
3.集合临时表取数
初学者,本文有任何不妥,错误的地方,希望得到同学们的指点,以期进步,感恩。
步骤
n个临时表计算,最后聚合取数。
1.组宽表:
筛选,取数(排除重复列),之后所有的表都可以from ‘宽表’,减少重复代码,也不会遗漏筛选条件。
2.审题:
要计算的字段与要求。整理出:需求字段有哪些,哪些直接求,哪些需要子查询的(一般两个及以上聚合函数/窗口函数需要子查询)
- 产品ID(product_id):产品的ID。——直接取
- 总销售额(total_sales):该产品的2023年总销售额。——1个聚合函数
- 单价(unit_price):产品的单价。——直接取
- 总销量(total_quantity):该产品的2023年总销售数量。——1个聚合函数
- 月平均销售额(avg_monthly_sales):2023年该产品的月均销售额。
——因为本题已经说明销售额总和/12即可,只涉及1个聚合函数,因此可以直接求
但,如果实际业务场景,要求反映实际销售月份的平均水平,需用 AVG(月销售额)(需先聚合计算月销售额),那么就涉及2个聚合函数:avg(),sum()则需要子查询处理。
- 单月最高销量(max_monthly_quantity):2023年该产品的最大月销售数量。
计算逻辑:先求每产品每月销量,再取最高。
拆解涉及参数:产品,月份,销量聚合,最大值(聚合)——2个聚合函数,需要子查特殊处理。
因为要求里没说最大值有多个的情况,这里就偷懒用max(),不用窗口函数比大小了
提醒自己:出现求极值/排名top,一般会需要子查询特殊处理,要有菊花一紧的意识。
- 购买量最多的客户年龄段(customer_age_group):2023年购买该产品数量最多的顾客的年龄段(1-10,11-20,21-30,31-40,41-50,51-60,61+)
计算逻辑:先求每个产品每年龄段的购买量,再取最多
拆解涉及参数:产品,年龄段,销量聚合,最大值(聚合),两个聚合函数,需要子查特殊处理。
同时这里要求出现相同极值的情况,因此需要用窗口函数,销售额最大所以desc,年龄取小所以升序。大降小升
3.集合上文临时表,最后取数即可
t0:宽表 t1: 一般值 t2:单月最高销量 t3:购买量最多的客户年龄段 最后 聚合
代码
with kb as(
select a.*,b.customer_age,c.unit_price
from orders a join customers b on a.customer_id=b.customer_id
join products c on a.product_id=c.product_id
where year(order_date)='2023'),
t1 as(#一般值
select
product_id,sum(quantity*unit_price) total_sales,unit_price,
sum(quantity) total_quantity,
round(sum(quantity*unit_price)/12,2) avg_monthly_sales
from kb
group by 1,3),
t2 as(#单月最高销量
select product_id,max(ts) max_monthly_quantity from
(select product_id,month(order_date) m,sum(quantity) ts
from kb
group by 1,2)d
group by 1),
t3 as(#购买量最多的客户年龄段
select
*,dense_rank()over(partition by product_id order by s desc,customer_age_group) rk
from(
select product_id,sum(quantity) s,
case when customer_age between 1 and 10 then '1-10'
when customer_age between 11 and 20 then '11-20'
when customer_age between 21 and 30 then '21-30'
when customer_age between 31 and 40 then '31-40'
when customer_age between 41 and 50 then '41-50'
when customer_age between 51 and 60 then '51-60'
when customer_age >61 then '61+' end customer_age_group
from kb
group by 1,3)e)
#聚合
select
t1.*,t2.max_monthly_quantity,t3.customer_age_group
from t1 left join t2 on t1.product_id=t2.product_id left join t3 on t1.product_id=t3.product_id
where rk=1
order by total_sales desc,product_id
踩过的坑:
- t2虽然只要求max,但一定要加产品id,因为最后聚合需要这个作为主键,也不要忘记group by 一下噢。
- 聚合函数/窗口函数的嵌套使用要小心些



京公网安备 11010502036488号