首页 > 试题广场 >

统计每个产品的销售情况

[编程题]统计每个产品的销售情况
  • 热度指数:10505 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
数据查询需求说明
为了对每个产品的营销进行新的策划,需要统计2023年每个产品的销售情况。现有三个原始数据表格:customers(顾客)、products(产品)和orders(订单),其结构如下:

  customers(顾客)
字段名 数据类型 说明
customer_id(顾客ID) 整数 顾客的唯一标识符
customer_name(顾客姓名) 字符串(最大长度50) 顾客的姓名
customer_email(顾客邮箱) 字符串(最大长度50) 顾客的电子邮箱地址
customer_age(顾客年龄) 整数 顾客的年龄
PRIMARY KEY (customer_id) - 将customer_id设置为主键,确保每个顾客ID的唯一性。
products(产品)
字段名 数据类型 说明
product_id(产品ID) 整数 产品的唯一标识符
product_name(产品名称) 字符串(最大长度50) 产品的名称
unit_price(单价) 十进制数(保留两位小数) 产品的单价
PRIMARY KEY (product_id) - 将product_id设置为主键,确保每个产品ID的唯一性。
orders(订单)
字段名 数据类型 说明
order_id(订单ID) 整数 订单的唯一标识符
customer_id(顾客ID) 整数 顾客的ID,对应customers表格中的customer_id
product_id(产品ID) 整数 产品的ID,对应products表格中的product_id
quantity(数量) 整数 产品的数量
order_date(订单日期) 日期 订单的日期
PRIMARY KEY (order_id) - 将order_id设置为主键,确保每个订单ID的唯一性。

查询要求

根据上述表格,查询2023年每个产品的以下信息:

  • 产品IDproduct_id):产品的ID。
  • 总销售额total_sales):该产品的2023年总销售额。
  • 单价unit_price):产品的单价。
  • 总销量total_quantity):该产品的2023年总销售数量。
  • 月平均销售额avg_monthly_sales):2023年该产品的月均销售额。
  • 单月最高销量max_monthly_quantity):2023年该产品的最大月销售数量。
  • 购买量最多的客户年龄段customer_age_group):2023年购买该产品数量最多的顾客的年龄段(1-10,11-20,21-30,31-40,41-50,51-60,61+


排序规则

  • 按照每个产品的总销售额降序排列。
  • 如果总销售额一致,则按照产品的ID升序排列。
  • 当存在两个客户年购买量都是最高时,customer_age_group展示年龄小的顾客的年龄段。


计算说明

  • 总销售额 = 总销量 × 单价
  • 月平均销售额 = 总销售额 / 12
  • 所有计算结果保留两位小数。

【示例】
customers(顾客)表格

products(产品)表格

orders(订单)表格

按要求查询出来的结果

示例说明

假设产品104的2023年销售总量是6,单价是120.00,则:

  • 总销售额 = 6 × 120 = 720.00
  • 月平均销售额 = 720 / 12 = 60.00
  • 购买量最大的客户ID是2的Bob,年龄是30,所在年龄段是21-30。



示例1

输入

drop table if exists customers ;
drop table if exists products ;
drop table if exists orders ;
CREATE TABLE customers (
    customer_id INT,
    customer_name VARCHAR(50),
    customer_email VARCHAR(50),
    customer_age INT,
    PRIMARY KEY (customer_id)
);

INSERT INTO customers (customer_id, customer_name, customer_email, customer_age) VALUES
(1, 'Alice', 'alice@example.com', 25),
(2, 'Bob', 'bob@example.com', 30),
(3, 'Charlie', 'charlie@example.com', 22),
(4, 'David', 'david@example.com', 18),
(5, 'Eve', 'eve@example.com', 35);

CREATE TABLE products (
    product_id INT,
    product_name VARCHAR(50),
    unit_price DECIMAL(10, 2),
    PRIMARY KEY (product_id)
);

INSERT INTO products (product_id, product_name, unit_price) VALUES
(101, 'Product A', 50.00),
(102, 'Product B', 75.00),
(103, 'Product C', 100.00),
(104, 'Product D', 120.00),
(105, 'Product E', 90.00);

CREATE TABLE orders (
    order_id INT,
    customer_id INT,
    product_id INT,
    quantity INT,
    order_date DATE,
    PRIMARY KEY (order_id)
);

INSERT INTO orders (order_id, customer_id, product_id, quantity, order_date) VALUES
(1, 1, 101, 2, '2023-01-15'),
(2, 2, 102, 3, '2023-02-20'),
(3, 3, 103, 1, '2023-03-10'),
(4, 4, 104, 2, '2023-04-05'),
(5, 5, 105, 4, '2023-05-12'),
(6, 1, 102, 2, '2023-06-18'),
(7, 2, 103, 3, '2023-07-22'),
(8, 3, 104, 1, '2023-08-30'),
(9, 4, 105, 2, '2023-09-14'),
(10, 5, 101, 4, '2023-10-25'),
(11, 1, 103, 2, '2023-11-08'),
(12, 2, 104, 3, '2023-12-19');

输出

product_id|total_sales|unit_price|total_quantity|avg_monthly_sales|max_monthly_quantity|customer_age_group
104|720.00|120.00|6|60.00|3|21-30
103|600.00|100.00|6|50.00|3|21-30
105|540.00|90.00|6|45.00|4|31-40
102|375.00|75.00|5|31.25|3|21-30
101|300.00|50.00|6|25.00|4|31-40
with t1 as #计算 前5个字段
    (select 
        p.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 products p join orders o on p.product_id=o.product_id
    group by p.product_id,unit_price)
,t2 as #计算“产品的 最大 月销售数量”
    (select 
        product_id
        ,month(order_date) month
        ,sum(quantity) monthly_quantity
    from orders
    group by product_id,month)
,t3 as #计算“产品的 最大 月销售数量”
    (select 
        product_id
        ,max(monthly_quantity) max_monthly_quantity 
    from t2
    group by product_id)
,t4 as #计算顾客"年龄段"、“产品购买数”
    (select 
        product_id
        ,o.customer_id
        ,sum(quantity)  某顾客购买该产品的数量
        ,row_number()over(partition by product_id order by sum(quantity) desc,customer_age) c_quantity_rk
        ,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'
        else '61+' end customer_age_group 
    from customers c join orders o on c.customer_id=o.customer_id
    group by o.customer_id,product_id,customer_age_group)
,t5 as #计算 购买该产品的数量最多的顾客的年龄段
    (select 
        product_id,customer_age_group from t4
    where c_quantity_rk=1)
select 
    t1.product_id
    ,total_sales
    ,unit_price
    ,total_quantity
    ,avg_monthly_sales
    ,max_monthly_quantity
    ,customer_age_group
from t1
    join t3 on t1.product_id=t3.product_id
    join t5 on t1.product_id=t5.product_id
order by total_sales desc,product_id

发表于 2025-03-23 16:35:05 回复(1)
with t as (select product_id,min(customer_age) as kk from (select d.product_id,customer_age
from orders d
inner join customers e
inner join (select product_id,max(quantity) as max_q from orders 
group by product_id) as l
on d.customer_id=e.customer_id
and d.product_id=l.product_id
where quantity=max_q) aa
group by aa.product_id),
y as (select product_id,max(monthly_quantity) as max_monthly_quantity from (select product_id,sum(quantity) as monthly_quantity from orders 
group by product_id,DATE_FORMAT(order_date, '%Y-%m') ) bb
group by product_id)

select q.product_id,total_sales,unit_price,total_quantity,round(avg_monthly_sales,2) as avg_monthly_sales,y.max_monthly_quantity,(case when t.kk>=1 and t.kk<=10 then '1-10' when t.kk>=11 and t.kk<=20 then '11-20' when t.kk>=21 and t.kk<=30 then '21-30' when t.kk>=31 and t.kk<=40 then '31-40' when t.kk>=41 and t.kk<=50 then '41-50' when t.kk>=51 and t.kk<=60 then '51-60' else '61+' end) as customer_age_group
from(
select a.product_id,sum(quantity) *unit_price as total_sales,unit_price,
sum(quantity) as total_quantity,(sum(quantity) *unit_price)/12 as avg_monthly_sales
from orders a
inner join products b
inner join customers c
on a.customer_id=c.customer_id
and a.product_id=b.product_id
group by a.product_id,unit_price
order by total_sales desc,a.product_id) q
left join t on q.product_id=t.product_id
left join y on q.product_id=y.product_id

难吐了,4小时,你知道我这四小时是怎么过的吗? 
啊啊啊啊啊啊啊!!!1



发表于 2025-03-19 17:53:48 回复(4)
select
a.product_id,
total_sales,
unit_price,
total_quantity,
round(avg_monthly_sales, 2),
max_monthly_quantity,
customer_age_group
from
(
select
p.product_id,
unit_price,
sum(quantity) total_quantity,
sum(quantity) * unit_price total_sales,
sum(quantity) * unit_price / 12 avg_monthly_sales
from
products p
join orders o on p.product_id = o.product_id
where
year (order_date) = 2023
group by
p.product_id,
unit_price
) a 
join (
select
product_id,
concat ('-', year (order_date), month (order_date)) yf,
sum(quantity) max_monthly_quantity,
row_number() over (
partition by
product_id
order by
sum(quantity) desc
) rk
from
orders
where
year (order_date) = 2023
group by
product_id,
concat ('-', year (order_date), month (order_date))
) b on a.product_id = b.product_id
join (
select
product_id,
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 > 60 then '60+'
end as customer_age_group,
row_number() over (
partition by
product_id
order by
sum(quantity) desc,
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 > 60 then '60+'
end
) rk1
from
orders o
join customers c on o.customer_id = c.customer_id
where
year (order_date) = 2023
group by
product_id,
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 > 60 then '60+'
end
) c on a.product_id = c.product_id
where
rk = 1
and rk1 = 1
order by
total_sales desc,
product_id


发表于 2025-06-11 11:35:00 回复(0)
with 
a as(select product_id , month(order_date) month, sum(quantity) quan,
row_number()over(partition by product_id order by sum(quantity) desc) ro
from orders group by product_id , month(order_date)),
b as (select o.product_id , (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'
    else '61+' end) ag , sum(quantity) cnt,
    row_number()over(partition by product_id order by sum(quantity) desc) ra
    from customers c
    join orders o on o.customer_id = c.customer_id 
    group by product_id,ag)
select o.product_id,
sum(p.unit_price*o.quantity) total_sales,
p.unit_price,
sum(o.quantity) total_quantity,
round(sum(p.unit_price*o.quantity)/12,2) avg_monthly_sales,
a.quan max_monthly_quantity,
b.ag customer_age_group
from orders o 
join products p on p.product_id = o.product_id
join a on a.product_id = o.product_id
join b on b.product_id = o.product_id
where a.ro = 1 and b.ra = 1
group by o.product_id,a.quan,b.ag
order by total_sales desc,product_id 
前4条数据简单,5和6分别通过a表和b表用窗口函数来进行排序,其实拆开并不难,就是东西多了杂到一起就晕了
发表于 2025-05-02 22:58:03 回复(0)
#计算商品总销售额,单价,总数,月均销售额
with t1 as
(select o.product_id as product_id, unit_price*sum(quantity) as total_sales, unit_price, sum(quantity) as total_quantity, round(unit_price*sum(quantity)/12,2) as avg_monthly_sales from orders o left join products p on o.product_id = p.product_id
group by product_id),
#计算最大月销售量
t2 as 
(select product_id, month, month_quantity as max_monthly_quantity from
(select product_id, month(order_date) as month, sum(quantity) as month_quantity, row_number()over(partition by product_id order by sum(quantity) desc) as rk from orders
group by product_id, month(order_date)) s1
where rk = 1),
#处理年龄
t3 as
(select product_id, customer_age, 
(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
(select product_id,o.customer_id as customer_id, sum(quantity) as sq, customer_age, row_number()over(partition by product_id order by sum(quantity) desc, customer_age) as rk from orders o left join customers c on o.customer_id = c.customer_id
group by product_id, o.customer_id) s2
where rk = 1)
#连接表
select t1.product_id as product_id, total_sales, unit_price, total_quantity, avg_monthly_sales, max_monthly_quantity, customer_age_group from t1 join t2 on t1.product_id = t2.product_id
join t3 on t1.product_id = t3.product_id
order by total_sales desc, product_id

发表于 2025-04-20 04:34:19 回复(0)
没什么说的,关键是耐心。
with t1 as(
    select p.*, o.order_id,o.customer_id,o.quantity,o.order_date,
    c.customer_name,  c.customer_email, c.customer_age,
    ELT(INTERVAL(c.customer_age,1,11,21,31,41,51,61),'1-10','11-20','21-30','31-40','41-50','51-60','61+') as age_group,
    month(o.order_date) as order_month
    from products p
    left join orders o
    on o.product_id=p.product_id
    left join customers c
    on c.customer_id=o.customer_id
    where year(o.order_date)=2023
)
,
result1 as(
    select product_id, max(total_quantity) as max_monthly_quantity
    from (
        select product_id,
        sum(quantity) as total_quantity
        from t1 
        group by product_id,order_month
    ) tmp1
    group by product_id
)
,
t3 as (
    select product_id,
    sum(quantity) as total_quantity,
    age_group
    from t1 
    group by product_id,age_group
)
,
result2 as(
    select product_id,age_group
    from  (
            select *, row_number() over(partition by product_id order by total_quantity desc, field(age_group,'1-10','11-20','21-30','31-40','41-50','51-60','61+') ) as rn from t3 
          ) tmp2
    where rn=1
)
,
result0 as(
    select 
    product_id,
    sum(quantity*unit_price) as total_sales,
    unit_price,
    sum(quantity) as total_quantity,
    round(sum(quantity*unit_price) /12.0, 2) as avg_monthly_sales
    from t1
    group by product_id
)

select r0.*,
r1.max_monthly_quantity,
r2.age_group as customer_age_group
from result0 r0
join result1 r1
on r0.product_id=r1.product_id
join result2 r2
on r0.product_id=r2.product_id
order by total_sales desc, product_id asc



发表于 2025-04-15 14:17:39 回复(0)
select t2.product_id, total_sales,unit_price, total_quantity,
avg_monthly_sales,max_monthly_quantity,customer_age_group
from(
select p.product_id,sum(quantity) *unit_price as total_sales,unit_price,sum(quantity) as total_quantity,round(sum(quantity) *unit_price/12,2) as avg_monthly_sales
from products p join orders o
on p.product_id=o.product_id
group by p.product_id,unit_price)t1
join
(select product_id,quantity as max_monthly_quantity,
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'
     else '61+ '
end as customer_age_group
from(
select product_id,quantity,customer_age,row_number() over(partition by product_id order by quantity desc,customer_age) as rk
from customers c join orders o
on c.customer_id=o.customer_id)t
where rk=1)t2
on t1.product_id=t2.product_id
order by total_sales desc,product_id;
select t2.product_id, total_sales,unit_price, total_quantity,
avg_monthly_sales,max_monthly_quantity,customer_age_group
from(
select p.product_id,sum(quantity) *unit_price as total_sales,unit_price,sum(quantity) as total_quantity,round(sum(quantity) *unit_price/12,2) as avg_monthly_sales
from products p join orders o
on p.product_id=o.product_id
group by p.product_id,unit_price)t1
join
(select product_id,quantity as max_monthly_quantity,
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'
     else '61+ '
end as customer_age_group
from(
select product_id,quantity,customer_age,row_number() over(partition by product_id order by quantity desc,customer_age) as rk
from customers c join orders o
on c.customer_id=o.customer_id)t
where rk=1)t2
on t1.product_id=t2.product_id
order by total_sales desc,product_id;

发表于 2025-04-13 16:10:01 回复(1)
购买量最多的客户年龄段(customer_age_group)
1、每个产品每个用户购买数量
2、根据每个产品每个用户购买数量和用户年龄,统计购买数量降序年龄升序排名
3、排名第一的用户年龄
4、处理年龄区间

select product_id , total_sales , unit_price, 
         total_quantity,
        round(avg_monthly_sales,2) as avg_monthly_sales,
         max_monthly_quantity,
        case when maxq_age>=1 and maxq_age<=10 then '1-10'
        when maxq_age>=11 and maxq_age<=20 then'11-20'
        when maxq_age>=21 and maxq_age<=30 then'21-30'
        when maxq_age>=31 and maxq_age<=40 then'31-40'
        when maxq_age>=41 and maxq_age<=50 then'41-50'
        when maxq_age>=51 and maxq_age<=60 then'51-60'
        when maxq_age>=61 then'61+'
        end as customer_age_group
from (
    select product_id ,sum(sales) as total_sales , max(unit_price ) as unit_price, 
        sum(quantity) aS total_quantity,
        sum(sales)/12 aS avg_monthly_sales,
        max(mon_quantity) as max_monthly_quantity,
        排名第一的用户年龄
        max(case when rn =1 then customer_age end ) as maxq_age
    from (

        select customer_id , product_id ,quantity, sales, order_date,unit_price,customer_age,
            cus_quantity,
            mon_quantity,
            根据每个产品每个用户购买数量和用户年龄,统计购买数量降序年龄升序排名
            row_number()over(partition by product_id order by cus_quantity desc,customer_age) as rn
        from (
            select o.customer_id , o.product_id ,quantity, quantity*p.unit_price as sales, order_date,unit_price,c.customer_age,
            每个产品每个用户购买数量
                sum(quantity)over(partition by o.product_id, o.customer_id) as cus_quantity,
                月购买数量
                sum(quantity)over(partition by o.product_id, substr(order_date,1,7)) as mon_quantity
            from orders o inner join products p on o.product_id= p.product_id
            inner join customers c on o.customer_id= c.customer_id
            where substr(order_date,1,4)='2023'
        ) t 
    ) t
     group by product_id
)t

order by 2 desc ,1




发表于 2025-04-07 13:40:06 回复(1)
#关联products和orders求得前六项
with a as(
    select p.product_id,
        round(sum(quantity*unit_price),2) total_sales,
        unit_price,
        sum(quantity) total_quantity,
        round((sum(quantity*unit_price))/12,2) avg_monthly_sales,
        max(quantity) max_monthly_quantity
    from products p 
    join orders o using(product_id)
    where year(order_date)=2023 
    group by p.product_id
),
#关联customers和orders分类,并用窗口函数根据product_id分组customer_age升序排序rk
 b as(
    select *,
    rank() over(partition by product_id order by customer_age) rk
    from 
    (select c.customer_id,product_id,customer_age,
    max(sum(quantity)) over(partition by product_id ) num,
    sum(quantity) um,
        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'
        else '61+' end customer_age_group
    from customers c left join orders o using(customer_id)
    group by c.customer_id,product_id)d
    where num=um 
)
#关联a、b表,并得购买量都是最高时最小年龄段
select a.product_id,     total_sales,     unit_price,     total_quantity,     avg_monthly_sales,     max_monthly_quantity,     customer_age_group from a join b using(product_id) where rk=1 order by total_sales desc,product_id

发表于 2025-03-26 17:57:49 回复(1)
select
    product_id,
    total_sales,
    unit_price,
    total_quantity,
    avg_monthly_sales,
    max(max_monthly_quantity) over(partition by product_id) as max_monthly_quantity,
    max(customer_age_group) over(partition by product_id) as customer_age_group
from (
    select
        product_id,
        sum(quantity) over(partition by product_id, year(order_date)) as total_quantity,
        unit_price,
        (sum(quantity) over(partition by product_id, year(order_date))) * unit_price as total_sales,
        round((sum(quantity) over(partition by product_id, year(order_date))) * unit_price / 12, 2) as avg_monthly_sales,
        max(quantity) over(partition by product_id, month(order_date)) as max_monthly_quantity,
        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'
            else '60+'
        end as customer_age_group,
        rank() over(partition by product_id order by quantity desc, customer_age) as rk
    from (
        select
            o.product_id,
            unit_price,
            quantity,
            order_date,
            customer_age
        from orders as o
        join customers as c on o.customer_id = c.customer_id
        join products as p on o.product_id = p.product_id  
    ) as b
    where year(order_date) = 2023
) as a
where rk = 1
order by total_sales desc, product_id asc

发表于 2025-06-25 13:32:33 回复(0)
with t1 as
(
    select
    product_id,customer_id,customer_age
    from
    (
        select
        t.product_id,t.customer_id,c.customer_age,
        row_number() over(partition by t.product_id order by t.qua desc,c.customer_age) as rn
        from
        (
            select
            product_id,customer_id,
            sum(quantity) as qua
            from orders
            where year(order_date)=2023
            group by product_id,customer_id
        ) t
        join customers c on t.customer_id=c.customer_id
    ) r
    where rn=1
),
t2 as
(
    select
    product_id,
    max(s) as ms
    from
    (
        select
        product_id,month(order_date) as m,
        sum(quantity) as s
        from orders
        where year(order_date)=2023
        group by product_id,month(order_date)
    ) t
    group by product_id
),
t3 as
(
    select
    o.product_id,
    sum(o.quantity)*avg(p.unit_price) as total_sales,
    avg(p.unit_price) as unit_price,
    sum(o.quantity) as total_quantity,
    sum(o.quantity)*avg(p.unit_price)/12 as avg_monthly_sales
    from orders o
    join products p on o.product_id=p.product_id
    where year(o.order_date)=2023
    group by o.product_id
)

select
t3.product_id,
round(t3.total_sales,2) as total_sales,
round(t3.unit_price,2) as unit_price,
t3.total_quantity,
round(t3.avg_monthly_sales,2) as avg_monthly_sales,
t2.ms as max_monthly_quantity,
case when t1.customer_age between 1 and 10 then '1-10'
     when t1.customer_age between 11 and 20 then '11-20'
     when t1.customer_age between 21 and 30 then '21-30'
     when t1.customer_age between 31 and 40 then '31-40'
     when t1.customer_age between 41 and 50 then '41-50'
     when t1.customer_age between 51 and 60 then '51-60'
     when t1.customer_age > 60 then '61+'
end as customer_age_group
from t1
join t2 on t1.product_id=t2.product_id
join t3 on t2.product_id=t3.product_id
order by t3.total_sales desc,t3.product_id
发表于 2025-06-22 18:54:15 回复(0)
with t1 as (select *
from orders o
left join products using(product_id)
left join customers using(customer_id)),
t2 as (select product_id,
sum(unit_price*quantity) total_sales,
unit_price, sum(quantity) total_quantity,
round(sum(unit_price*quantity)/12,2) avg_monthly_sales,
max(quantity) max_monthly_quantity
from t1
group by product_id,unit_price
),
t3 as (select t2.product_id product_id,
total_sales,
t2.unit_price unit_price,
total_quantity,
avg_monthly_sales,
max_monthly_quantity,
t1.customer_age customer_age,
(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'
else '60+'
end) as customer_age_group
from t2 left join t1 on t2.product_id= t1.product_id and t2.max_monthly_quantity=t1.quantity
order by total_sales desc, product_id),
t4 as (select product_id, customer_age,rank()over (partition by product_id order by customer_age) rk
from t3)
select t4.product_id product_id,
total_sales,
unit_price,
total_quantity,
avg_monthly_sales,
max_monthly_quantity,
customer_age_group
from t4 left join t3 on t4.product_id= t3.product_id and t4.customer_age = t3.customer_age
where rk=1
order by total_sales desc, product_id ASC
发表于 2025-06-20 22:12:22 回复(0)

with t0 as

(

select a.product_id

        ,unit_price

        ,quantity

        ,case when customer_age 11 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'

            else '61+' end as age_group

        ,order_date

from orders as a

join customers as b on a.customer_id=b.customer_id

join products as c on a.product_id=c.product_id

where year(order_date)='2023'

)

,t1 as

( # 按产品和月份计算销售数据

select product_id

        ,month(order_date) as month

        ,sum(quantity*unit_price) as month_total_price

        ,sum(quantity) as month_quantity

from t0

group by 1,2

)

,t2 as

( #每个产品购买数量最多的顾客的年龄段(order by当存在两个客户年购买量都是最高时)

select product_id

        ,age_group as customer_age_group

from

(

    select product_id

            ,age_group

            ,row_number() over(partition by product_id order by total_quantity desc,product_id) as rn

    from

    (

        select product_id

                ,age_group

                ,sum(quantity) as total_quantity

        from t0

        group by 1,2

    ) tmp

) p

where rn=1

)

,t3 as

(

select product_id

        ,sum(month_total_price) as total_sales

        ,sum(month_quantity) as total_quantity

        ,round(sum(month_total_price)/12,2) as avg_monthly_sales

        ,max(month_quantity) as max_monthly_quantity

from t1

group by 1

)

select distinct a.product_id

    ,total_sales

    ,unit_price

    ,total_quantity

    ,avg_monthly_sales

    ,max_monthly_quantity

    ,customer_age_group

from t3 as a

inner join t2 as b on a.product_id=b.product_id

inner join t0 as c on a.product_id=c.product_id and b.product_id=c.product_id

order by 2 desc,1

发表于 2025-06-20 19:00:00 回复(0)
第一次写这么久 吐了,还好有AI,提交报错时可问AI
with t as (
    select o.product_id,
            month(o.order_date) as month_date,
            sum(o.quantity) as month_quantity
             
            
    from orders as o
    left join products as p
      on o.product_id=p.product_id
     where year(o.order_date)= '2023'
    group by o.product_id, month(o.order_date) ),

b as (select product_id,
             customer_age_group
    from(
      select o.product_id,
            sum(o.quantity) as age_total_quantity,
            case 
        when c.customer_age between 1 and 10 then '1-10'
        when c.customer_age between 11 and 20 then '11-20'
        when c.customer_age between 21 and 30 then '21-30'
        when c.customer_age between 31 and 40 then '31-40'
        when c.customer_age between 41 and 50 then '41-50'
        when c.customer_age between 51 and 60 then '51-60'
        else '61+' end  as customer_age_group,
        row_number() over (partition by o.product_id order by sum(o.quantity) desc) as rn
        from orders as o
        left join customers as c
        on o.customer_id=c.customer_id
        where year(o.order_date)= '2023'
        group by o.product_id,customer_age_group) as r

        where rn=1
)


select p.product_id,
      sum(p.unit_price*o.quantity) as total_sales,
      p.unit_price,
      sum(o.quantity) as total_quantity,
      round(sum(p.unit_price*o.quantity)/12,2) as avg_monthly_sales,
      max(t.month_quantity) as max_monthly_quantity,
      b.customer_age_group

from orders as o
left join products as p 
on o.product_id=p.product_id
left join b
on o.product_id=b.product_id

left join t
on o.product_id=t.product_id AND MONTH(o.order_date) = t.month_date  -- 精确匹配月份,否则3个sum聚合字段会虚高



where year(o.order_date)='2023'
group by p.product_id, p.unit_price,b.customer_age_group
order by total_sales desc,p.product_id

发表于 2025-06-20 16:58:52 回复(0)
尽力了,测试过了提交过不了,不知道为什么


-- 拿到产品ID、总销售额、单价、总销量、月均销售额的字段
with t1 as(select p.product_id,
       sum(quantity)*unit_price total_sales,
       max(unit_price) unit_price,sum(quantity) total_quantity,
       round(sum(quantity)*unit_price/12,2) avg_monthly_sales
from orders o
left join products p
using(product_id)
group by p.product_id),t2 as
(select product_id,month(order_date),sum(quantity) quantity
from orders
group by product_id,month(order_date)
),t3 as(   -- 拿到每个产品最大月销量
select product_id,max(quantity) max_monthly_quantity
from t2
group by product_id),t4 as(
select *,
      case when customer_age<=10 then "1-10"
      when customer_age<=20 then "11-20"
      when customer_age<=30 then "21-30"
      when customer_age<=40 then "31-40"
      when customer_age<=50 then "41-50"
      when customer_age<=60 then "51-60"
      else "60+"
      end customer_age_group
from customers
left join orders o
using(customer_id)),t5 as(
select product_id,customer_age_group,count(*),
        rank() over(
            partition by product_id
            order by count(*) desc,customer_age_group desc
        ) px
from t4
group by product_id,customer_age_group),t6 as(
select product_id,customer_age_group
from t5
where px=1)
select *
from t1
left join t3
using(product_id)
left join t6
using(product_id)
order by total_sales desc,product_id asc

发表于 2025-06-20 15:00:53 回复(0)
#这题的数据有些多,建议由浅入深
with tabel1 as
(select
o.product_id,
o.quantity*p.unit_price total,
o.quantity,
p.unit_price,
date_format(o.order_date, '%Y-%m') order_date,
sum(quantity)over(partition by o.product_id, order_date) month_quantity,
sum(quantity)over(partition by o.product_id, o.customer_id) user_quantity,
o.customer_id,
case when c.customer_age between 11 and 20 then '11-20'
     when c.customer_age between 21 and 30 then '21-30'
     when c.customer_age between 31 and 40 then '31-40'
     when c.customer_age between 41 and 50 then '41-50'
     end
     customer_age_group
from orders o left join customers c on o.customer_id = c.customer_id
     left join products p on o.product_id = p.product_id
where year(o.order_date) = '2023'),

tabel2 as
(select
product_id, sum(total) total_sales, unit_price, sum(quantity) total_quantity, round(sum(total)/12, 2) avg_monthly_sales, max(month_quantity) max_monthly_quantity
from tabel1
group by product_id),

tabel3 as
(select
product_id, customer_id
from
(select
product_id, customer_id,row_number()over(partition by product_id order by sq desc) nums
from
(select
product_id, customer_id,sum(quantity) sq
from tabel1
group by product_id, customer_id) as p) as q
where nums = 1)

select
distinct
t2.product_id, t2.total_sales, t2.unit_price, t2.total_quantity,t2.avg_monthly_sales, t2.max_monthly_quantity,
t1.customer_age_group
from tabel3 t3 join tabel2 t2 on t3.product_id = t2.product_id
     join tabel1 t1 on t1.customer_id = t3.customer_id
order by t2.total_sales desc, t2.product_id
发表于 2025-06-20 00:12:31 回复(0)
select a.*,b.customer_age_group
from (
select product_id
,sum(total_sales)total_sales
,unit_price
,sum(quantity)total_quantity
,round(sum(total_sales)/12,2) avg_monthly_sales
,max(max_sale_month) max_monthly_quantity
from (
select a.product_id
,quantity*unit_price total_sales
,unit_price
,quantity 
,sum(quantity)over(partition by month(order_date),product_id ) max_sale_month
from orders a 
left join products b 
on a.product_id = b.product_id
where year(order_date)='2023'
)t 
group by product_id,unit_price
)a 
left join (

select product_id
,case when customer_age<=10 then '1-10'
    when customer_age<=20 then '11-20'
    when customer_age<=30 then '21-30'
    when customer_age<=40 then '31-40'
    when customer_age<=50 then '41-50'
    when customer_age<=60 then '51-60'
    else '61+' end customer_age_group
,sum(quantity) quantity
,row_number()over(partition by product_id order by sum(quantity) desc ,min(customer_age_group)) rn
from orders a 
left join  customers c 
on a.customer_id = c.customer_id
where year(order_date)='2023'
group by product_id
,case when customer_age<=10 then '1-10'
    when customer_age<=20 then '11-20'
    when customer_age<=30 then '21-30'
    when customer_age<=40 then '31-40'
    when customer_age<=50 then '41-50'
    when customer_age<=60 then '51-60'
    else '61+' end
    
)b 
on a.product_id = b.product_id and b.rn = 1
order by total_sales desc ,a.product_id

发表于 2025-06-18 22:27:33 回复(0)
WITH t1 AS(SELECT
    o.product_id,
    SUM(quantity * unit_price) AS total_sales,
    unit_price,
    SUM(quantity) AS total_quantity,
    ROUND(SUM(quantity * unit_price) / 12 , 2) AS avg_monthly_sales
FROM orders o
JOIN products p ON(o.product_id = p.product_id)
JOIN customers c ON(o.customer_id = c.customer_id)
GROUP BY o.product_id, unit_price
ORDER BY total_sales DESC, product_id ASC),
t2 AS(
    SELECT
        MONTH(order_date) AS month,
        product_id,
        customer_id,
        quantity,
        ROW_NUMBER() OVER(PARTITION BY product_id ORDER BY quantity DESC) AS rk
    FROM orders
    GROUP BY month, product_id, quantity, customer_id
),
t3 AS(
    SELECT 
        t2.customer_id,
        customer_age
    FROM t2
    JOIN customers c ON(t2.customer_id = c.customer_id)

)
SELECT
    DISTINCT t2.product_id,
    total_sales,
    unit_price,
    total_quantity,
    avg_monthly_sales,
    quantity AS max_monthly_quantity,
    CASE WHEN t3.customer_age BETWEEN 1 AND 10 THEN '21-30'
        WHEN t3.customer_age BETWEEN 11 AND 20 THEN '11-20'
        WHEN t3.customer_age BETWEEN 21 AND 30 THEN '21-30'
        WHEN t3.customer_age BETWEEN 31 AND 40 THEN '31-40'
        WHEN t3.customer_age BETWEEN 41 AND 50 THEN '41-50'
        WHEN t3.customer_age BETWEEN 51 AND 60 THEN '51-60'
        WHEN t3.customer_age >60 THEN '61+'
    END AS customer_age_group
FROM t1
JOIN t2 ON(t1.product_id = t2.product_id)
JOIN t3 ON(t2.customer_id = t3.customer_id)
WHERE rk = 1
ORDER BY total_sales DESC, t2.product_id
没看答案自己磨磨蹭蹭写出来了!!
发表于 2025-06-18 22:16:58 回复(1)
select product_id,total_sales,unit_price,total_quantity,round(avg_monthly_sales,2) avg_monthly_sales,max_monthly_quantity,customer_age_group
from 
(select product_id,sum(total) over(partition by product_id) total_sales,unit_price,sum(quantity) over(partition by product_id) total_quantity,sum(total) over(partition by product_id)/12 avg_monthly_sales,max(quantity) over(partition by product_id) max_monthly_quantity,age_tag customer_age_group,qrnk
from
(select product_id,customer_id,quantity,unit_price,quantity*unit_price total,age_tag,rank() over(partition by product_id order by quantity desc,customer_age) qrnk
from 
(select o.product_id,o.customer_id,customer_age,quantity,unit_price,case when customer_age <=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'
else '61+' end as age_tag
from orders o
left join products p
on o.product_id = p.product_id
left join customers c
on o.customer_id = c.customer_id) t1)t2)t3
where qrnk = 1
order by total_sales desc,product_id

发表于 2025-06-18 15:02:05 回复(0)
 -- 2023年产品销售情况统计查询 - 详细注释版
-- WITH关键字:定义公用表表达式(CTE),创建临时命名结果集
-- product_basics:CTE的名称,用于计算每个产品的基础统计数据
WITH
    product_basics AS (
        -- SELECT:选择要返回的列
        SELECT
            p.product_id, -- p是products表的别名,product_id是产品唯一标识符字段
            p.unit_price, -- unit_price是products表中的单价字段(DECIMAL类型)
            SUM(o.quantity) as total_quantity, -- SUM()聚合函数:对quantity字段求和; o是orders表别名; AS定义列别名
            SUM(o.quantity * p.unit_price) as total_sales, -- 计算总销售额:每笔订单(数量×单价)的总和
            ROUND(SUM(o.quantity * p.unit_price) / 12, 2) as avg_monthly_sales -- ROUND()函数:四舍五入; 参数1是表达式; 参数2是小数位数(2位)
            -- FROM子句:指定主表,orders表别名为o
        FROM
            orders o
            -- JOIN:内连接关键字,连接两表的公共字段
            -- products表别名为p,ON指定连接条件
            JOIN products p ON p.product_id = o.product_id -- 连接条件:产品表的product_id = 订单表的product_id
            -- WHERE子句:过滤条件
            -- YEAR()函数:提取日期的年份部分,参数是order_date字段(DATE类型)
        WHERE
            YEAR(o.order_date) = 2023 -- 只统计2023年的订单数据
            -- GROUP BY:分组子句,按指定字段分组,使聚合函数生效
        GROUP BY
            p.product_id,
            p.unit_price -- 按产品ID和单价分组,确保每个产品一行结果
    ),
    -- 第二个CTE:计算单月最高销量
    monthly_max AS (
        -- 外层查询:从月度汇总中找最大值
        SELECT
            product_id, -- 产品ID字段
            MAX(monthly_qty) as max_monthly_quantity -- MAX()聚合函数:找出最大值; monthly_qty来自子查询
            -- FROM子句:使用子查询作为数据源
        FROM
            (
                -- 内层子查询:计算每个产品每个月的销量
                SELECT
                    product_id, -- 产品ID字段
                    YEAR(order_date) as year_num, -- 提取年份,别名为year_num
                    MONTH(order_date) as month_num, -- MONTH()函数:提取月份(1-12),别名为month_num
                    SUM(quantity) as monthly_qty -- 计算每个月的销量总和,别名为monthly_qty
                FROM
                    orders -- 从orders表查询
                WHERE
                    YEAR(order_date) = 2023 -- 筛选2023年数据
                    -- 三重分组:按产品、年份、月份分组
                GROUP BY
                    product_id,
                    YEAR(order_date),
                    MONTH(order_date) -- 确保每个产品每个月一行数据
            ) monthly_totals -- 子查询别名为monthly_totals
        GROUP BY
            product_id -- 按产品ID分组,配合MAX函数找出每个产品的最大月销量
    ),
    -- 第三个CTE:计算每个客户对每个产品的总购买量
    customer_product_totals AS (
        SELECT
            o.product_id, -- 订单表中的产品ID字段
            o.customer_id, -- 订单表中的客户ID字段(外键,关联customers表)
            SUM(o.quantity) as customer_total_qty -- 计算该客户购买该产品的总数量
        FROM
            orders o -- 从订单表查询,别名为o
        WHERE
            YEAR(o.order_date) = 2023 -- 只统计2023年的购买数据
        GROUP BY
            o.product_id,
            o.customer_id -- 双重分组:按产品ID和客户ID分组,得到客户-产品购买矩阵
    ),
    -- 第四个CTE:找出每个产品购买量最多的客户年龄段
    top_customers AS (
        SELECT
            cpt.product_id, -- cpt是customer_product_totals的别名
            MIN(c.customer_age) as min_age -- MIN()聚合函数:找最小值; c.customer_age是客户年龄字段(INT类型)
            -- 连接客户-产品购买表和客户表
        FROM
            customer_product_totals cpt -- 主表:客户产品购买汇总
            JOIN customers c ON cpt.customer_id = c.customer_id -- 连接客户表获取年龄信息,连接条件是customer_id
            -- WHERE子句:复杂的筛选条件
            -- (字段1, 字段2) IN (子查询):多字段IN条件,同时匹配产品ID和购买量
        WHERE
            (cpt.product_id, cpt.customer_total_qty) IN (
                -- 子查询:找出每个产品的最大购买量
                SELECT
                    product_id,
                    MAX(customer_total_qty) -- 每个产品的最大客户购买量
                FROM
                    customer_product_totals -- 从客户产品购买表查询
                GROUP BY
                    product_id -- 按产品分组
            )
        GROUP BY
            cpt.product_id -- 按产品分组,配合MIN函数选择年龄最小的客户
    )
    -- 主查询:整合所有CTE的结果
SELECT
    pb.product_id, -- pb是product_basics的别名,获取产品ID
    pb.total_sales, -- 从第一个CTE获取总销售额
    pb.unit_price, -- 从第一个CTE获取单价
    pb.total_quantity, -- 从第一个CTE获取总销量
    pb.avg_monthly_sales, -- 从第一个CTE获取月平均销售额
    mm.max_monthly_quantity, -- mm是monthly_max的别名,获取单月最高销量
    -- CASE表达式:条件判断,类似if-else语句
    CASE
        -- WHEN条件 THEN结果:如果年龄在1-10之间,返回'1-10'
        WHEN tc.min_age BETWEEN 1 AND 10  THEN '1-10' -- BETWEEN...AND:范围条件,包含边界值
        WHEN tc.min_age BETWEEN 11 AND 20  THEN '11-20' -- tc是top_customers的别名
        WHEN tc.min_age BETWEEN 21 AND 30  THEN '21-30'
        WHEN tc.min_age BETWEEN 31 AND 40  THEN '31-40'
        WHEN tc.min_age BETWEEN 41 AND 50  THEN '41-50'
        WHEN tc.min_age BETWEEN 51 AND 60  THEN '51-60'
        ELSE '61+' -- ELSE:默认情况,年龄大于60的归为'61+'
    END as customer_age_group -- END:结束CASE表达式,AS定义别名
    -- FROM子句:主表是第一个CTE
FROM
    product_basics pb
    -- LEFT JOIN:左外连接,保留左表(pb)的所有记录,即使右表没有匹配
    LEFT JOIN monthly_max mm ON pb.product_id = mm.product_id -- 连接条件:产品ID相等
    LEFT JOIN top_customers tc ON pb.product_id = tc.product_id -- 连接客户年龄段信息
    -- ORDER BY:排序子句
ORDER BY
    pb.total_sales DESC,
    pb.product_id ASC;

 -- DESC降序(大到小),ASC升序(小到大)
-- 先按总销售额降序,再按产品ID升序

SQL代码逐行详解

整体结构说明

这个查询使用了**CTE(公用表表达式)**的方式,将复杂查询分解为4个逻辑步骤,最后在主查询中整合结果。


第一部分:product_basics CTE

WITH product_basics AS (
  • 作用:定义第一个CTE,用于计算每个产品的基础统计数据
  • CTE:Common Table Expression,类似于临时表,可以在后续查询中引用
SELECT 
        p.product_id,
        p.unit_price,
        SUM(o.quantity) as total_quantity,
        SUM(o.quantity * p.unit_price) as total_sales,
        ROUND(SUM(o.quantity * p.unit_price) / 12, 2) as avg_monthly_sales
  • p.product_id:获取产品ID
  • p.unit_price:获取产品单价
  • SUM(o.quantity) as total_quantity:计算该产品2023年总销量
  • SUM(o.quantity * p.unit_price) as total_sales:计算总销售额(数量×单价的总和)
  • ROUND(.../ 12, 2) as avg_monthly_sales:计算月平均销售额(总销售额÷12个月,保留2位小数)
FROM orders o
    JOIN products p ON p.product_id = o.product_id
  • 连接订单表和产品表,通过product_id关联
  • 这样可以获取到订单的数量信息和产品的单价信息
WHERE YEAR(o.order_date) = 2023
  • 关键筛选条件:只统计2023年的订单数据
  • YEAR()函数提取订单日期的年份
GROUP BY p.product_id, p.unit_price
),
  • 按产品ID和单价分组,确保每个产品得到一行汇总数据
  • 分组后SUM函数才能计算每个产品的总和

第二部分:monthly_max CTE

monthly_max AS (
  • 定义第二个CTE,专门计算每个产品的单月最高销量
SELECT 
        product_id,
        MAX(monthly_qty) as max_monthly_quantity
  • 从月度汇总数据中找出每个产品的最大月销量
FROM (
        SELECT 
            product_id,
            YEAR(order_date) as year_num,
            MONTH(order_date) as month_num,
            SUM(quantity) as monthly_qty
        FROM orders
        WHERE YEAR(order_date) = 2023
        GROUP BY product_id, YEAR(order_date), MONTH(order_date)
    ) monthly_totals
  • 内层子查询
    • YEAR(order_date)和MONTH(order_date):提取年份和月份
    • SUM(quantity) as monthly_qty:计算每个产品每个月的销量总和
    • GROUP BY product_id, YEAR(order_date), MONTH(order_date):按产品、年、月分组
    • 结果:每个产品每个月一行数据,包含该月的销量总和
GROUP BY product_id
),
  • 外层按产品ID分组,使用MAX函数找出每个产品所有月份中销量最高的月份

第三部分:customer_product_totals CTE

customer_product_totals AS (
  • 第三个CTE,计算每个客户对每个产品的总购买量
SELECT 
        o.product_id,
        o.customer_id,
        SUM(o.quantity) as customer_total_qty
  • 汇总每个客户购买每个产品的总数量
  • 一个客户可能多次购买同一产品,这里把所有购买累加
FROM orders o
    WHERE YEAR(o.order_date) = 2023
    GROUP BY o.product_id, o.customer_id
),
  • 同样只统计2023年数据
  • 按产品ID和客户ID分组,得到客户-产品的购买量矩阵

第四部分:top_customers CTE

top_customers AS (
  • 第四个CTE,找出每个产品购买量最多的客户年龄段
SELECT 
        cpt.product_id,
        MIN(c.customer_age) as min_age
  • MIN(c.customer_age):当有多个客户并列购买量最多时,选择年龄最小的
FROM customer_product_totals cpt
    JOIN customers c ON cpt.customer_id = c.customer_id
  • 连接客户表获取年龄信息
WHERE (cpt.product_id, cpt.customer_total_qty) IN (
        SELECT product_id, MAX(customer_total_qty)
        FROM customer_product_totals
        GROUP BY product_id
    )
  • 复杂筛选条件
    • 内层查询:SELECT product_id, MAX(customer_total_qty)找出每个产品的最大购买量
    • 外层条件:只保留购买量等于最大值的记录
    • 这样筛选出每个产品购买量最多的客户(可能有多个并列)
GROUP BY cpt.product_id
)
  • 按产品分组,配合MIN函数,确保每个产品只返回一个年龄(最小的)

第五部分:主查询

SELECT 
    pb.product_id,
    pb.total_sales,
    pb.unit_price,
    pb.total_quantity,
    pb.avg_monthly_sales,
    mm.max_monthly_quantity,
  • 从前面的CTE中获取基础数据
CASE 
        WHEN tc.min_age BETWEEN 1 AND 10 THEN '1-10'
        WHEN tc.min_age BETWEEN 11 AND 20 THEN '11-20'
        WHEN tc.min_age BETWEEN 21 AND 30 THEN '21-30'
        WHEN tc.min_age BETWEEN 31 AND 40 THEN '31-40'
        WHEN tc.min_age BETWEEN 41 AND 50 THEN '41-50'
        WHEN tc.min_age BETWEEN 51 AND 60 THEN '51-60'
        ELSE '61+'
    END as customer_age_group
  • CASE语句:将具体年龄转换为年龄段标签
  • 按照题目要求的年龄段分类
FROM product_basics pb
LEFT JOIN monthly_max mm ON pb.product_id = mm.product_id
LEFT JOIN top_customers tc ON pb.product_id = tc.product_id
  • 连接所有CTE的结果
  • 使用LEFT JOIN确保即使某些数据缺失,产品信息也不会丢失
ORDER BY pb.total_sales DESC, pb.product_id ASC;
  • 排序规则
    • 首先按总销售额降序(销售额高的在前)
    • 销售额相同时按产品ID升序(ID小的在前)

核心设计思想

  1. 分步骤处理:将复杂逻辑拆分为4个独立的CTE,每个CTE负责一个特定计算
  2. 避免重复计算:基础数据计算一次,后续步骤复用
  3. 处理边界情况:使用LEFT JOIN和MIN函数处理并列情况
  4. 数据完整性:确保每个产品都有完整的统计信息

这种写法的优点是逻辑清晰、易于调试和维护,缺点是代码较长,但对于复杂的业务需求来说是很好的解决方案。

发表于 2025-06-16 16:00:07 回复(0)