解题思路整理

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

踩过的坑:

  1. t2虽然只要求max,但一定要加产品id,因为最后聚合需要这个作为主键,也不要忘记group by 一下噢。
  2. 聚合函数/窗口函数的嵌套使用要小心些