题目描述

(通过次数2,074 | 提交次数4,411,通过率47.02%)

表: Experiments
+-----------------+------+
| Column Name     | Type |
+-----------------+------+
| experiment_id   | int  |
| platform        | enum |
| experiment_name | enum |
+-----------------+------+
experiment_id 是这个表的主键.
platform 是枚举类型的,取值是这三种 ('Android', 'IOS', 'Web') 之一.
experiment_name 也是枚举类型的,取值是这三种 ('Reading', 'Sports', 'Programming') 之一.
这个表包含有关随机实验人员进行的实验的 ID、用于做实验的平台以及实验名称的信息。

写一个 SQL 查询语句,以报告在给定三个实验平台中每种实验完成的次数。请注意,每一对(实验平台、实验名称)都应包含在输出中,包括平台上实验次数是零的。
结果可以以任意顺序给出。

查询的结果如下所示:
示例:
输入:
Experiments table:
+---------------+----------+-----------------+
| experiment_id | platform | experiment_name |
+---------------+----------+-----------------+
| 4             | IOS      | Programming     |
| 13            | IOS      | Sports          |
| 14            | Android  | Reading         |
| 8             | Web      | Reading         |
| 12            | Web      | Reading         |
| 18            | Web      | Programming     |
+---------------+----------+-----------------+
输出:
+----------+-----------------+-----------------+
| platform | experiment_name | num_experiments |
+----------+-----------------+-----------------+
| Android  | Reading         | 1               |
| Android  | Sports          | 0               |
| Android  | Programming     | 0               |
| IOS      | Reading         | 0               |
| IOS      | Sports          | 1               |
| IOS      | Programming     | 1               |
| Web      | Reading         | 2               |
| Web      | Sports          | 0               |
| Web      | Programming     | 1               |
+----------+-----------------+-----------------+
解释:
在安卓平台上, 我们只做了一个"Reading" 实验.
在 "IOS" 平台上,我们做了一个"Sports" 实验和一个"Programming" 实验.
在 "Web" 平台上,我们做了两个"Reading" 实验和一个"Programming" 实验.

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/count-the-number-of-experiments
//测试数据
Create table If Not Exists Experiments (experiment_id int, platform ENUM('Android', 'IOS', 'Web'), experiment_name ENUM('Reading', 'Sports', 'Programming'));

insert into Experiments (experiment_id, platform, experiment_name) values ('4', 'IOS', 'Programming');
insert into Experiments (experiment_id, platform, experiment_name) values ('13', 'IOS', 'Sports');
insert into Experiments (experiment_id, platform, experiment_name) values ('14', 'Android', 'Reading');
insert into Experiments (experiment_id, platform, experiment_name) values ('8', 'Web', 'Reading');
insert into Experiments (experiment_id, platform, experiment_name) values ('12', 'Web', 'Reading');
insert into Experiments (experiment_id, platform, experiment_name) values ('18', 'Web', 'Programming');

解题思路

根据题目描述,总共有3类平台、3个实验项目,需要计算每个平台、每个实验项目进行的次数。即使某个实验项目并没有在某平台实验过,也需要返回一条0次的记录。
很明显,我们需要平台与实验项目的两两组合结果。这使用笛卡尔积可以实现。
然后与Experiments表进行关联后,分组统计不同组合的数量即可。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。
with
tmp1 as (
    select 'Android' platform
    union all
    select 'IOS' platform
    union all
    select 'Web' platform
),
tmp2 as (
    select 'Reading' experiment_name
    union all
    select 'Sports' experiment_name
    union all
    select 'Programming' experiment_name
)
select
    a.platform,
    b.experiment_name,
    count(c.experiment_id) num_experiments
from tmp1 a
inner join tmp2 b
on 1=1
left join Experiments c
on a.platform = c.platform
and b.experiment_name = c.experiment_name
group by a.platform,
    b.experiment_name;
picture loss