# 电商面试题：如何分析复杂业务？

![](/files/-MV6kmOkQ7OOw7u9dZMm)

**【题目】**

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

![](/files/-MV6ll-O_e5kejO08Idu)

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

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

![](/files/-MV6lrKhGOQsJXkjuB8_)

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

![](/files/-MV6m8MUfgD5SZWBBpe1)

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

![](/files/-MV6mUT9xWZr3bQCU-rQ)

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

![](/files/-MV6mXx5Z7ScK4LwEDcF)

**【解题步骤】**

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

![](/files/-MV6mfH3MeDdmJxHcHgO)

使用[逻辑树分析方法](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649246563\&idx=2\&sn=3ffe509999d144d23dec5acc101fc2ef\&chksm=835fc353b4284a45ce01391453fe2fec1b225bbd6bbdb67dd7f304aacdd4f21f60d0b27ba309\&scene=21#wechat_redirect)，将复杂问题拆解为简单问题：

（1）查询结果：品牌名，品类名，电商平台、销售额

（2）筛选条件：品类号列表（12，33，45，99，1001），2019 年

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

**1. 查询结果：品牌名，品类名，电商平台、销售额**

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

![](/files/-MV6mirMGu8Vsy0U6b9A)

```sql
select *
from 品牌表 as a 
inner join 月销售统计表 as c
on a.品牌号 = c.品牌号
inner join 品类表 as b
on b.品类号 = c.品类号;
```

![](/files/-MV6mpLa3vrdaqodaRyN)

把这个查询结果当做临时表

![](/files/-MV6ngZo4jbKxpnabbw3)

**2. 筛选条件：品类号列表（12，33，45，99，1001），2019 年**

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

```sql
select *
from 临时表
where 品类号 in(12，33，45，99，1001)
      and year(月份) = 2019;
```

查询结果

![](/files/-MV6nvmuY5Y23s_1HnJM)

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

看到 "每个"，要想到《[猴子 从零学会 sql](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649247566\&idx=2\&sn=5af748b677eb72028764dde0577675fb\&chksm=835fc77eb4284e68e8cfe3f08c5a671b9e080b2651f20b40b1c793ffda4042ae43ad8f35a755\&scene=21#wechat_redirect)》里见过的这类问题要用分组汇总。

```sql
select sum(销售额) as 销售额
from 临时表
where 品类号 in(12，33，45，99，1001)
      and year(月份) = 2019
group by 电商平台,品牌号,品类号;
```

查询结果

![](/files/-MV6nzbbc7NyJ0zXyXc1)

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

```sql
select a.品牌号,品牌名,b.品类号,品类名,电商平台,sum(销售额) as 销售额
from 品牌表 as a 
inner join 月销售统计表 as c
on a.品牌号 = c.品牌号
inner join 品类表 as b
on b.品类号 = c.品类号
where 品类号 in(12，33，45，99，1001)
      and year(月份)= 2019
group by a.品牌号,品牌名,b.品类号,品类名,电商平台;
```

查询结果

![](/files/-MV6oQwQfsGH9c4tLn2K)

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

![](/files/-MV6oGZ_ttYXVo7olV3h)

使用[逻辑树分析方法](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649246563\&idx=2\&sn=3ffe509999d144d23dec5acc101fc2ef\&chksm=835fc353b4284a45ce01391453fe2fec1b225bbd6bbdb67dd7f304aacdd4f21f60d0b27ba309\&scene=21#wechat_redirect)将复杂问题变简单：

（1）查询结果：品牌号、品牌名、品类数量

（2）筛选条件：2019 年

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

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

（5）销售额大于等于 10000

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

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

![](/files/-MV6oWKn9tklFeUXjCtD)

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

![](/files/-MV6o_dsPc-_xEuQSJYM)

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

![](/files/-MV6ojqnkHCfcpuJwN2L)

查询结果

![](/files/-MV6onTl2BbJoXYE0S7R)

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

**2. 筛选条件：2019 年**

```sql
select *
from 临时表
where year(月份) = 2019;
```

查询结果

![](/files/-MV6onTl2BbJoXYE0S7R)

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

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

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

查询结果

![](/files/-MV6peaAiHAI73GAQPFb)

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

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

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

查询结果

![](/files/-MV6pkMmsRQXC7-Y5RLy)

**5. 销售额大于等于 10000**

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

查询结果

![](/files/-MV6q0XT4iBKmwb_WqcP)

输出格式如下：

![](/files/-MV6q5nJTPJyTer3MIg3)

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

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

查询结果

![](/files/-MV6sxqspURvxuVvU86Q)

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

![](/files/-MV6t0sv5Uy5Dan4qVO8)

使用[逻辑树分析方法](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649246563\&idx=2\&sn=3ffe509999d144d23dec5acc101fc2ef\&chksm=835fc353b4284a45ce01391453fe2fec1b225bbd6bbdb67dd7f304aacdd4f21f60d0b27ba309\&scene=21#wechat_redirect)，将复杂问题拆解为简单问题：

（1）查询结果：品牌号，品牌名，平台 1 总销售额

（2）筛选条件：2019 年

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

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

**1. 查询结果：品牌号，品牌名，平台 1 总销售额**

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

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

![](/files/-MV6tAfpWwUgYpMrVQby)

把查询结果当做临时表。

![](/files/-MV6tEg8HlmJxpPRnW8M)

**2.** **筛选条件：2019 年**

```sql
select *
from 临时表
where year(月份) = 2019;
```

查询结果

![](/files/-MV6u0HG4RCr4wxKa4Ia)

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

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

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

查询结果

![](/files/-MV6u8f9jueF8OhWFeQ2)

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

观察输出格式要求。

![](/files/-MV6uFc4MkTp30n_GO4s)

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

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

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

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

查询结果

![](/files/-MV6uU0zCAkTd1d9wDHg)

观察输出格式要求：

![](/files/-MV6ubn4nBaRChNGrVcT)

最终答案：

```sql
select a.品牌号,品牌名,sum(销售额) as '平台1总销售额'
from 品牌表 as a left join 月销售统计表 as c 
on a.品牌号 = c.品牌号
where year(月份) = 2019
group by a.品牌号,品牌名,电商平台
having 电商平台 = 1 and a.品牌号 in (
select a.品牌号
from 品牌表 as a left join 月销售统计表 as c 
on a.品牌号 = c.品牌号
where year(月份) = 2019
group by a.品牌号,电商平台
having 电商平台 = 2 and sum(销售额) = 0
)
order by sum(销售额) desc
limit 30;
```

查询结果

![](/files/-MV6vLx7zW3VEAQJPBMj)

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

![](/files/-MV6vQ4ydPcVAjvihlTl)

使用[逻辑树分析方法](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649246563\&idx=2\&sn=3ffe509999d144d23dec5acc101fc2ef\&chksm=835fc353b4284a45ce01391453fe2fec1b225bbd6bbdb67dd7f304aacdd4f21f60d0b27ba309\&scene=21#wechat_redirect)，将复杂问题拆解为简单问题：

（1）查询结果：品牌号，品牌名，全平台累计销售额

（2）筛选条件：2019 年

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

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

**1. 查询结果：品牌号，品牌名，全平台累计销售额**

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

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

![](/files/-MV6vavf5frdmQiFj314)

查询结果

![](/files/-MV6vp6p9jSRkisbXqpC)

**2. 筛选条件：2019 年**

where 子句限制条件

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

查询结果

![](/files/-MV6vp6p9jSRkisbXqpC)

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

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

![](/files/-MV6vavf5frdmQiFj314)

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

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

查询结果

![](/files/-MV6w1HM3YqfnC0Mw3Ei)

将上述结果作为临时表，表名为：销售统计表

2）分别**同时**都能进入销售额 Top 50 的品牌：

这是《猴子 从零学过 sql》里讲过的 [top N 问题。](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649247630\&idx=1\&sn=663ab9bb96107e560f1fe52b53faba97\&chksm=835fc7beb4284ea8d3e006deec3836df0bccc29ade3f4915b76cdb0f52a704df0ee2e53af6c2\&scene=21#wechat_redirect)

先从简单的入手：查询每个平台销售额最高的**两个**品牌（即对平台进行分组，对销售额进行排序），套用之前讲过的 [top N 问题](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649247630\&idx=1\&sn=663ab9bb96107e560f1fe52b53faba97\&chksm=835fc7beb4284ea8d3e006deec3836df0bccc29ade3f4915b76cdb0f52a704df0ee2e53af6c2\&scene=21#wechat_redirect)模板。

```sql
#TOP N问题SQL模板
select *
from (
   select*,
         row_number() over (partition by 要分组的列名
                       order by 要排序的列名 desc) as ranking
   from 表名) as a
where ranking <= N;
```

对应这个案例就是：

```sql
select *
from (
   select*,
         row_number() over (partition by 电商平台
                       order by 总销售额 desc) as ranking
   from 销售统计表) as a
where ranking <=2;
```

![](/files/-MV6wHsPp1NdaYoi9Z0k)

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

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

```sql
select 品牌号,sum(总销售额) as 平台总销售额
from (
   select*,
         row_number() over (partition by 电商平台
                       order by 总销售额 desc) as ranking
   from 销售统计表) as a
where ranking <=2
group by 品牌号
having count(电商平台) >= 2;
```

![](/files/-MV6wO9GQlM6Af65ilNT)

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

```sql
select 品牌号,sum(总销售额) as 全平台累计销售额
from (
   select*,
         row_number() over (partition by 电商平台
                       order by 总销售额 desc) as ranking
   from 销售统计表) as a
where ranking <=50
group by 品牌号
having count(电商平台) >= 2;
```

查询结果

![](/files/-MV6wWN3qV-do5WySoCd)

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

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

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

![](/files/-MV6xn9lJgqIK9Am5L1c)

![](/files/-MV6xriJ6c-qwXkvMpZJ)

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

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

查询结果

![](/files/-MV6ynI9QyhDlM0K59gN)

最终答案：

```sql
with 销售统计表(品牌号,电商平台,总销售额)
as
(select 品牌号,电商平台,sum(销售额) as 总销售额
from 月销售统计表
where year(月份) = 2019
group by 品牌号,电商平台),
前五十品牌号 as
(select 品牌号,sum(总销售额) as 全平台累计销售额
from (
   select *,
          row_number() over(partition by 电商平台
                       order by 总销售额 desc) as ranking
   from 销售统计表) as a
where ranking <=50
group by 品牌号
having count(电商平台) >= 2)
select a.品牌号,a.品牌名,全平台累计销售额
from 品牌表 as a right join 前五十品牌号 as b
on a.品牌号 = b.品牌号
where a.品牌号 in (b.品牌号)
group by a.品牌号,a.品牌名;
```

查询结果

![](/files/-MV6ynI9QyhDlM0K59gN)

**【本题考点】**

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

2）考查多表联结，TOPN 问题。

3）考查思维能力，面对多个条件和多个表，如何用[逻辑树分析方法](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649246563\&idx=2\&sn=3ffe509999d144d23dec5acc101fc2ef\&chksm=835fc353b4284a45ce01391453fe2fec1b225bbd6bbdb67dd7f304aacdd4f21f60d0b27ba309\&scene=21#wechat_redirect)理清思路，解决问题。

4）top n 问题的应用变化

**【举一反三】**

本题的模拟数据可以在公众号（猴子聊人物）对话框回复 “资料”，在下面网盘路径中获取到

![](/files/-MV6zCBqPmLoR9sFydZO)

![](/files/-MV6zRQ5PWE20dkaskcd)

![](/files/-MV6zVrDgeNbSQLAI3DN)

推荐：[如何从零学会 sql？](http://mp.weixin.qq.com/s?__biz=MzAxMTMwNTMxMQ==\&mid=2649247566\&idx=2\&sn=5af748b677eb72028764dde0577675fb\&chksm=835fc77eb4284e68e8cfe3f08c5a671b9e080b2651f20b40b1c793ffda4042ae43ad8f35a755\&scene=21#wechat_redirect)

![](/files/-MV6z_u4PJc8fN7389gB)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://houzidata.gitbook.io/sql/di-5-zhang-xiang-mu-shi-zhan/dian-shang-mian-shi-ti-ru-he-fen-xi-fu-za-ye-wu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
