题目描述
(通过次数1,519 | 提交次数2,154,通过率70.52%)
表: 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 没有订阅。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/number-of-accounts-that-did-not-stream
//测试数据 Create table If Not Exists Subscriptions (account_id int, start_date date, end_date date); Create table If Not Exists Streams (session_id int, account_id int, stream_date date); insert into Subscriptions (account_id, start_date, end_date) values ('9', '2020-02-18', '2021-10-30'); insert into Subscriptions (account_id, start_date, end_date) values ('3', '2021-09-21', '2021-11-13'); insert into Subscriptions (account_id, start_date, end_date) values ('11', '2020-02-28', '2020-08-18'); insert into Subscriptions (account_id, start_date, end_date) values ('13', '2021-04-20', '2021-09-22'); insert into Subscriptions (account_id, start_date, end_date) values ('4', '2020-10-26', '2021-05-08'); insert into Subscriptions (account_id, start_date, end_date) values ('5', '2020-09-11', '2021-01-17'); insert into Streams (session_id, account_id, stream_date) values ('14', '9', '2020-05-16'); insert into Streams (session_id, account_id, stream_date) values ('16', '3', '2021-10-27'); insert into Streams (session_id, account_id, stream_date) values ('18', '11', '2020-04-29'); insert into Streams (session_id, account_id, stream_date) values ('17', '13', '2021-08-08'); insert into Streams (session_id, account_id, stream_date) values ('19', '4', '2020-12-31'); insert into Streams (session_id, account_id, stream_date) values ('13', '5', '2021-01-05');
解题思路
Subscriptions表保存了每个账户的订阅时间区间。
Streams表保存了账户所有的会话数据。
题目要求:查询在2021年有购买订阅,但没有任何会话的账户数。
对于第一个条件:在2021年有购买订阅。因为账户的订阅时间是个区间,而2021年包含2021-01-01至2021-12-31的时间区间。
如何判断两个时间区间有交叉呢?
抽象一下:假如有两个时间区间(a1,b1)和(a2,b2),当两个区间有交叉时,必须同时满足a1<=b2、b1>=a2。
具体到本题目,要满足2021年有购买订阅,必须满足条件:start_date <= '2021-12-31' and end_date >= '2021-01-01'。
对于第二个条件:2021年没有任何会话。可以使用NOT IN或NOT EXISTS实现。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select count(1) accounts_count from Subscriptions a where a.start_date <= '2021-12-31' and a.end_date >= '2021-01-01' and not exists ( select 1 from Streams b where a.account_id = b.account_id and b.stream_date between '2021-01-01' and '2021-12-31' );
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。