• SQL电商面试题:如何分析复杂业务?


    一、题目

            某公司在不同的电商平台上都有店铺,下面是该公司的销售数据表(每个表有一行示例数据)。

            现在需要解决的业务问题是:

            1.对于指定品类号范围(品类号列表:12,33,45,99,1001),查询2019年每个电商平台上每个品牌号对应每个品类号的累计销售额,输出格式如下

            2.查询2019年有5个以上(含5个)不同 品类号 的 单月单平台销售额大于等于10000的品牌列表,及对应的不同品类号 数量,输出格式如下

     

            3.查询2019年只在电商平台1上有销售额的品牌中(即排除电商平台为2时销售额累计大于0的品牌),电商平台1的累计销售额最大的Top30个品牌及对应的销售额,输出格式如下

     

            4.查询2019年在两个电商平台中分别同时都能进入销售额Top 50的品牌及对应的全电商平台累计销售额,输出格式如下

     二、解题步骤 

             问题1:对于指定品类号范围(品类号列表:12,33,45,99,1001),查询2019年每个电商平台上每个品牌号对应每个品类号的累计销售额,输出格式如下

    使用逻辑树分析方法,将复杂问题拆解为简单问题:

    (1)查询结果:品牌名,品类名,电商平台、销售额

    (2)筛选条件:品类号列表(12,33,45,99,1001),2019年

    (3)每个电商平台上每个品牌号对应每个品类号的累计销售额

    1.查询结果:品牌名,品类名,电商平台、销售额

    这些列分别来自3个不同的表,需要多表联结

    1. select *
    2. from 品牌表 as a
    3. inner join 月销售统计表 as c
    4. on a.品牌号 = c.品牌号
    5. inner join 品类表 as b
    6. on b.品类号 = c.品类号;

     

    2.筛选条件:品类号列表(12,33,45,99,1001),2019年

    使用where子句筛选出符合条件的数据

    1. select *
    2. from 临时表
    3. where 品类号 in(123345991001)
    4. and year(月份) = 2019;

     

    3.每个电商平台上每个品牌号对应每个品类号的累计销售额

    1. select sum(销售额) as 销售额
    2. from 临时表
    3. where 品类号 in(123345991001)
    4. and year(月份) = 2019
    5. group by 电商平台,品牌号,品类号;

     

    把临时表的sql套入上面就得到最终的sql:

    1. select a.品牌号,品牌名,b.品类号,品类名,电商平台,sum(销售额) as 销售额
    2. from 品牌表 as a
    3. inner join 月销售统计表 as c
    4. on a.品牌号 = c.品牌号
    5. inner join 品类表 as b
    6. on b.品类号 = c.品类号
    7. where 品类号 in(123345991001)
    8. and year(月份)= 2019
    9. group by a.品牌号,品牌名,b.品类号,品类名,电商平台;

     

            问题2:查询2019年有5个以上(含5个)不同品类号的单月单平台销售额大于等于10000的品牌列表,及对应的不同品类号数量,输出格式如下

     

    使用逻辑树分析方法将复杂问题变简单:

    (1)查询结果:品牌号、品牌名、品类数量

    (2)筛选条件:2019年

    (3)不同品类号的单月单平台的销售额

    (4)5个以上(含5个)不同品类号

    (5)销售额大于等于10000

    1.查询结果:品牌号、品牌名、品类数量

    查询结果涉及到2张表需要用到多表查询,用哪种联结呢?

     

            因为题目要求查询所有符合条件的品牌号,而品牌表包含了所有品牌号,所有需要以"品牌表"进行左联结,保留左边表(品牌表)里的全部数据。

             

    1. select *
    2. from 品牌表 as a
    3. left join 月销售统计表 as c
    4. on a.品牌号 = c.品牌号;

     把上面查询结果当做临时表。

    2.筛选条件:2019年

    1. select *
    2. from 临时表
    3. where year(月份) = 2019;

     

     3.不同品类号的单月单平台的销售额

    也就是每个品类号每个月每个平台,涉及到“每个”需要用到分组汇总。

    1. select sum(销售额)
    2. from 临时表
    3. where year(月份) = 2019
    4. group by 品类号,月份,电商平台;

     

    4.5个以上(含5个)不同品类号

    需要用count,distinct筛选出符合条件的数据。

    1. select sum(销售额) as 销售额
    2. from 临时表
    3. where year(月份) = 2019
    4. group by 品类号,月份,电商平台
    5. having count(distinct 品类号) >= 5;

     

    5.销售额大于等于10000

    1. select sum(销售额) as 销售额
    2. from 临时表
    3. where year(月份) = 2019
    4. group by 品类号,月份,电商平台
    5. having count(distinct 品类号) >= 5
    6. and 销售额>= 10000;

     

    把临时表的sql套入上面就得到最终的sql:

    1. select a.品牌号,品牌名,count(distinct 品类号) as 品类号数量
    2. from 品牌表 as a left join 月销售统计表 as c
    3. on a.品牌号 = c.品牌号
    4. where year(月份) = 2019
    5. group by a.品牌号,品牌名,月份,电商平台
    6. having count(distinct 品类号) >= 5
    7. and 销售额>= 10000;

     

            问题3:查询2019年只在电商平台1上有销售额的品牌中(即排除电商平台为2时销售额累计大于0的品牌),电商平台1的累计销售额最大的Top30个品牌及对应的销售额,输出格式如下

    使用逻辑树分析方法,将复杂问题拆解为简单问题:

    (1)查询结果:品牌号,品牌名,平台1总销售额

    (2)筛选条件:2019年

    (3)只在电商平台1上有销售额的品牌(即平台2的累计销售额为0)

    (4)电商平台1的累计销售额最大的Top30个品牌及对应的销售额

     

    1.查询结果:品牌号,品牌名,平台1总销售额

            输出的表中有品牌号,品牌名和销售额,所有需要用到联结,联结品牌表和月销售统计表,联结方式和问题2相同

    1. select *
    2. from 品牌表 as a left join 月销售统计表 as c
    3. on a.品牌号 = c.品牌号;

    2.筛选条件:2019年

    1. select *
    2. from 临时表
    3. where year(月份) = 2019;

     

    3.只在电商平台1上有销售额的品牌(即平台2的累计销售额为0)

            需要用group by对品牌号,电商平台分组,用having筛选出平台为2且销售额为0的品牌号作为子查询 

    1. select a.品牌号
    2. from 临时表
    3. where year(月份) = 2019
    4. group by a.品牌号,电商平台
    5. having 电商平台 = 2 and sum(销售额) = 0;

    4.电商平台1的累计销售额最大的Top30个品牌及对应的销售额

    观察输出格式要求。

    可以看出需要要用group by对品牌号,品牌名,电商平台分组,

    用having和 in 筛选出平台为1且在平台2销售额为0的Top30个品牌号,品牌名及对应的销售额。

    并用order by对销售额排序,并用limit取前30项

    1. select a.品牌号,sum(销售额) as '平台1总销售额'
    2. from 临时表
    3. where year(月份) = 2019
    4. group by a.品牌号,电商平台
    5. having 电商平台 = 1 and a.品牌号 in (子查询)
    6. order by sum(销售额) desc
    7. limit 30;

     

    最终答案:

    1. select a.品牌号,品牌名,sum(销售额) as '平台1总销售额'
    2. from 品牌表 as a left join 月销售统计表 as c
    3. on a.品牌号 = c.品牌号
    4. where year(月份) = 2019
    5. group by a.品牌号,品牌名,电商平台
    6. having 电商平台 = 1 and a.品牌号 in (
    7. select a.品牌号
    8. from 品牌表 as a left join 月销售统计表 as c
    9. on a.品牌号 = c.品牌号
    10. where year(月份) = 2019
    11. group by a.品牌号,电商平台
    12. having 电商平台 = 2 and sum(销售额) = 0
    13. )
    14. order by sum(销售额) desc
    15. limit 30;

     

            问题4:查询2019年在两个电商平台中分别同时都能进入销售额Top 50的品牌及对应的全电商平台累计销售额,输出格式如下 

    使用逻辑树分析方法,将复杂问题拆解为简单问题:

    (1)查询结果:品牌号,品牌名,全平台累计销售额

    (2)筛选条件:2019年

    (3)在两个电商平台中分别同时都能进入销售额Top 50的品牌

    (4)品牌对应的全电商平台累计销售额

    1.查询结果:品牌号,品牌名,全平台累计销售额

    输出的表中有品牌号,品牌名和销售额,所有需要用到联结,联结品牌表和月销售统计表,联结方式和问题2,问题3相同

    1. select *
    2. from 品牌表 as a left join 月销售统计表 as c
    3. on a.品牌号 = c.品牌号;

     

    2.筛选条件:2019年

    where子句限制条件

    1. select *
    2. from 品牌表 as a left join 月销售统计表 as c
    3. on a.品牌号 = c.品牌号
    4. where year(月份) = 2019;

     

    3.在两个电商平台中分别同时都能进入销售额Top 50的品牌

    1)因为月销售统计表中同品牌号同平台包含了不同的品类号

     所有应该用group by 按品牌号和电商平台分组,计算每个品牌在每个电商平台的累计销售额

    1. select 品牌号,电商平台,sum(销售额) as 总销售额
    2. from 月销售统计表
    3. where year(月份) = 2019
    4. group by 品牌号,电商平台;

     

    将上述结果作为临时表,表名为:销售统计表

    2)分别同时都能进入销售额Top 50的品牌:

    先从简单的入手:查询每个平台销售额最高的两个品牌(即对平台进行分组,对销售额进行排序),套用之前讲过的top N问题模板。

    1. #TOP N问题SQL模板
    2. select *
    3. from (
    4. select*,
    5. row_number() over (partition by 要分组的列名
    6. order by 要排序的列名 desc) as ranking
    7. from 表名) as a
    8. where ranking <= N;

     对应这个案例就是:

    1. select *
    2. from (
    3. select*,
    4. row_number() over (partition by 电商平台
    5. order by 总销售额 desc) as ranking
    6. from 销售统计表) as a
    7. where ranking <=2;

     

    那么在两个平台内都进入TOP2的品牌号呢?

    从上图可以看出,很显然是品牌号是158。因此我们需要对品牌号分组,用count对品牌号进行计数,大于或等于2则该品牌同时在两个平台均进入TOP2

    1. select 品牌号,sum(总销售额) as 平台总销售额
    2. from (
    3. select*,
    4. row_number() over (partition by 电商平台
    5. order by 总销售额 desc) as ranking
    6. from 销售统计表) as a
    7. where ranking <=2
    8. group by 品牌号
    9. having count(电商平台) >= 2;

     

    3)现在可以知道如何求在两个平台内都进入TOP50的品牌号了,只需把ranking <= 2改为ranking <= 50即可

    1. select 品牌号,sum(总销售额) as 全平台累计销售额
    2. from (
    3. select*,
    4. row_number() over (partition by 电商平台
    5. order by 总销售额 desc) as ranking
    6. from 销售统计表) as a
    7. where ranking <=50
    8. group by 品牌号
    9. having count(电商平台) >= 2;

     

    仍然将此表作为临时表,表名为:前五十品牌号

    4.品牌对应的全电商平台累计销售额

    因为输出格式中有品牌名,所以需要联结品牌表和前五十品牌号,因为输出的是进入TOP50的品牌号,所以需要以"前五十品牌表"进行右联结,保留右边表(前五十品牌表)里的全部数据。

     

    求出品牌号为前五十品牌号的品牌号、品牌、全平台累计销售额:

    1. select a.品牌号,a.品牌名,全平台累计销售额
    2. from 品牌表 as a right join 前五十品牌号 as b
    3. on a.品牌号 = b.品牌号
    4. where a.品牌号 in (b.品牌号)
    5. group by a.品牌号,a.品牌名;

     

    最终答案: 

    1. with 销售统计表(品牌号,电商平台,总销售额)
    2. as
    3. (select 品牌号,电商平台,sum(销售额) as 总销售额
    4. from 月销售统计表
    5. where year(月份) = 2019
    6. group by 品牌号,电商平台),
    7. 前五十品牌号 as
    8. (select 品牌号,sum(总销售额) as 全平台累计销售额
    9. from (
    10. select *,
    11. row_number() over(partition by 电商平台
    12. order by 总销售额 desc) as ranking
    13. from 销售统计表) as a
    14. where ranking <=50
    15. group by 品牌号
    16. having count(电商平台) >= 2)
    17. select a.品牌号,a.品牌名,全平台累计销售额
    18. from 品牌表 as a right join 前五十品牌号 as b
    19. on a.品牌号 = b.品牌号
    20. where a.品牌号 in (b.品牌号)
    21. group by a.品牌号,a.品牌名;

     

    【本题考点】

    1)考查对字符串的编程能力。

    2)考查多表联结,TOPN问题。

    3)考查思维能力,面对多个条件和多个表,如何用逻辑树分析方法理清思路,解决问题。

    4)top n问题的应用变化

    更多面试题以及可以关注公众号: 猴子数据分析

     

  • 相关阅读:
    蛇形填数 rust解法
    猿创征文|DEM分析分层重分类
    MybatisPlus(简单CURD,MP的实体类注解,MP条件查询,MP分页查询,MP批量操作,乐观锁,代码生成器)
    Windows窗体程序开启console(cmd命令行)
    第五章 数据库设计和事物
    TouchGFX之二进制字体
    使用Latex输入藏文字符
    深入理解Java线程间通信
    tensorflow张量运算
    AWS SAP-C02教程7--云迁移与灾备(DR)
  • 原文地址:https://blog.csdn.net/qq_41404557/article/details/126067603