【力扣 | SQL题 | 每日3题】力扣1990, 2020, 2051

1. 力扣1990:统计实验的数量

1.1 题目:

表: 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" 实验.

1.2 思路:

看注释。

1.3 题解:

sql 复制代码
-- 先创建一张关于三个实验平台每种实验的表
with tep1 as (
    select 'Android' platform 
    union all
    select 'IOS' platform 
    union all
    select 'Web' platform 
), tep2 as (
    select 'Reading' experiment_name
    union all
    select 'Sports' experiment_name
    union all
    select 'Programming' experiment_name
), tep3 as (
    select *
    from tep1, tep2
)
-- 然后与Experiments左外连接,experiment_id为null=>平台上实验次数为0
select t1.platform, t1.experiment_name, if(experiment_id is null, 0, count(*)) num_experiments 
from tep3 t1
left join Experiments t2
on t1.platform = t2.platform 
and t1.experiment_name = t2.experiment_name
group by t1.platform, t1.experiment_name

2. 力扣2020:无流量的账户数

2.1 题目:

表: Subscriptions

复制代码
+-------------+------+
| Column Name | Type |
+-------------+------+
| account_id  | int  |
| start_date  | date |
| end_date    | date |
+-------------+------+
account_id 是此表的主键列。
此表的每一行都表示帐户订阅的开始和结束日期。
请注意,始终开始日期 < 结束日期。

表: Streams

复制代码
+-------------+------+
| Column Name | Type |
+-------------+------+
| session_id  | int  |
| account_id  | int  |
| stream_date | date |
+-------------+------+
session_id是该表的主键列。
account_id是订阅表中的外键。
此表的每一行都包含与会话相关联的帐户和日期的信息。

编写SQL查询以报告在 2021 购买订阅但没有任何会话的帐 户数。

查询结果格式如下例所示。

示例1:

复制代码
输入: 
Subscriptions table:
+------------+------------+------------+
| account_id | start_date | end_date   |
+------------+------------+------------+
| 9          | 2020-02-18 | 2021-10-30 |
| 3          | 2021-09-21 | 2021-11-13 |
| 11         | 2020-02-28 | 2020-08-18 |
| 13         | 2021-04-20 | 2021-09-22 |
| 4          | 2020-10-26 | 2021-05-08 |
| 5          | 2020-09-11 | 2021-01-17 |
+------------+------------+------------+
Streams table:
+------------+------------+-------------+
| session_id | account_id | stream_date |
+------------+------------+-------------+
| 14         | 9          | 2020-05-16  |
| 16         | 3          | 2021-10-27  |
| 18         | 11         | 2020-04-29  |
| 17         | 13         | 2021-08-08  |
| 19         | 4          | 2020-12-31  |
| 13         | 5          | 2021-01-05  |
+------------+------------+-------------+
输出: 
+----------------+
| accounts_count |
+----------------+
| 2              |
+----------------+
解释:用户 4 和 9 在 2021 没有会话。
用户 11 在 2021 没有订阅。

2.2 思路:

2.3 题解:

sql 复制代码
with tep1 as (
    -- 查询那些人购买了订阅
    select account_id
    from Subscriptions
    where substring(start_date, 1, 4) = '2021' or substring(end_date, 1, 4) = '2021'
), tep2 as (
    -- 之所以这里我使用了distinct先去重,我觉得账户可能由多个会话,而且都不在2021年这种情况。
    select distinct account_id 
    from Streams 
    where substring(stream_date , 1, 4) <> '2021'
    and account_id in (
        select * from tep1
    )
)
select count(*) accounts_count  from tep2

3. 力扣2051:商店中每个成员的级别

3.1 题目:

表: Members

复制代码
+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| member_id   | int     |
| name        | varchar |
+-------------+---------+
member_id 是该表的主键。
该表的每一行都表示成员的名称和 ID。

表: Visits

复制代码
+-------------+------+
| Column Name | Type |
+-------------+------+
| visit_id    | int  |
| member_id   | int  |
| visit_date  | date |
+-------------+------+
visit_id 是该表的主键。
member_id 是 Members 表中 member_id 的外键。
该表的每一行都包含关于访问商店的日期和访问该商店的成员的信息。

表: Purchases

复制代码
+----------------+------+
| Column Name    | Type |
+----------------+------+
| visit_id       | int  |
| charged_amount | int  |
+----------------+------+
visit_id 是该表的主键。
visit_id 是访问表 visit_id 的外键。
该表的每一行都包含了关于在商店中消费的信息。

一个商店想对其成员进行分类。有三个层次:

  • "钻石" : 如果转换率 大于或等于 80.
  • "黄金" : 如果转换率 大于或等于 50 且小于 80.
  • "白银" : 如果转化率 小于 50.
  • "青铜": 如果该成员从未访问过该商店。

成员的 转化率(100 * 该会员的购买总数) / 该成员的总访问次数.

编写一个 SQL 来查询每个成员的 id、名称和类别。

任意顺序返回结果表。

查询结果格式如下所示。

示例 1:

复制代码
输入: 
Members 表:
+-----------+---------+
| member_id | name    |
+-----------+---------+
| 9         | Alice   |
| 11        | Bob     |
| 3         | Winston |
| 8         | Hercy   |
| 1         | Narihan |
+-----------+---------+
Visits 表:
+----------+-----------+------------+
| visit_id | member_id | visit_date |
+----------+-----------+------------+
| 22       | 11        | 2021-10-28 |
| 16       | 11        | 2021-01-12 |
| 18       | 9         | 2021-12-10 |
| 19       | 3         | 2021-10-19 |
| 12       | 11        | 2021-03-01 |
| 17       | 8         | 2021-05-07 |
| 21       | 9         | 2021-05-12 |
+----------+-----------+------------+
Purchases 表:
+----------+----------------+
| visit_id | charged_amount |
+----------+----------------+
| 12       | 2000           |
| 18       | 9000           |
| 17       | 7000           |
+----------+----------------+
输出: 
+-----------+---------+----------+
| member_id | name    | category |
+-----------+---------+----------+
| 1         | Narihan | Bronze   |
| 3         | Winston | Silver   |
| 8         | Hercy   | Diamond  |
| 9         | Alice   | Gold     |
| 11        | Bob     | Silver   |
+-----------+---------+----------+
解释: 
- id = 1 的成员 Narihan 没有访问过该商店。她获得了铜奖。
- id = 3 的成员 Winston 访问了商店一次,但没有购买任何东西。转化率=(100 * 0)/ 1 = 0。他获得了银奖。
- id = 8 的成员 Hercy 访问商店一次,购买一次。转化率=(100 * 1)/ 1 = 1。他获得了钻石奖。
- id = 9 的成员 Alice 访问了商店两次,购买了一次。转化率=(100 * 1)/ 2 = 50。她获得了金奖。
- id = 11 的用户 Bob 访问了商店三次,购买了一次。转化率=(100 * 1)/ 3 = 33.33。他获得了银奖。

3.2 思路:

写的好长,隔着一天没看懒的看这么长的sql 了。

3.3 题解:

sql 复制代码
with tep1 as (
    select member_id , t1.visit_id , charged_amount
    from Visits t1 
    left join Purchases t2 
    on t1.visit_id = t2.visit_id 
), tep2 as (
    select member_id, 
    (select count(charged_amount) from tep1 t2 where t1.member_id = t2.member_id)
    / (select count(*) from tep1 t2 where t1.member_id = t2.member_id) * 100 perc
    from tep1 t1
    group by member_id
), tep3 as (
    select member_id, 
    case when perc >= 80 then 'Diamond'
    when perc >= 50 then 'Gold'
    else 'Silver'
    end category 
    from tep2
)
select t1.member_id, name, category
from tep3 t1
join Members t2
on t1.member_id = t2.member_id 

union all

select member_id, name, 'Bronze' category
from Members 
where member_id not in (
    select member_id from tep1
)
相关推荐
Renas_TJOvO9 分钟前
排序算法汇总
java·数据结构·算法
Stardep11 分钟前
算法2—八大常用排序算法(下)
c语言·数据结构·笔记·算法·排序算法·1024程序员节
黑不溜秋的22 分钟前
C++ 模板专题 - 标签分派(Tag Dispatching)
开发语言·c++·算法
爱上语文27 分钟前
LeetCode每日一题
java·算法·leetcode
ProcedureStone38 分钟前
【算法】排序算法总结
c++·算法·排序算法
哦哦~92143 分钟前
Fluent和深度学习算法驱动的流体力学计算与应用
人工智能·深度学习·学习·算法
海波东1 小时前
oracle和mysql的区别常用的sql语句
sql·mysql·oracle
千里马-horse1 小时前
在OpenCL 中输出CLinfo信息
开发语言·c++·算法·opencl·1024程序员节
Y.O.U..1 小时前
Linux-计算机网络-epoll的LT,ET模式
linux·服务器·计算机网络·算法·1024程序员节