力扣数据库刷题--关于连续那些事儿

关于连续问题的那些事儿
链接:https://leetcode-cn.com/problems/active-users

1. #1454.活跃用户

写一个 SQL 查询, 找到活跃用户的 id 和 name。

活跃用户是指那些至少连续5 天登录账户的用户。

返回的结果表按照 id 排序。

SQL架构


Create table If Not Exists Accounts (id int, name varchar(10))

Create table If Not Exists Logins (id int, login_date date)

Truncate table Accounts

insert into Accounts (id, name) values ('1', 'Winston')

insert into Accounts (id, name) values ('7', 'Jonathan')

Truncate table Logins

insert into Logins (id, login_date) values ('7', '2020-05-30')

insert into Logins (id, login_date) values ('1', '2020-05-30')

insert into Logins (id, login_date) values ('7', '2020-05-31')

insert into Logins (id, login_date) values ('7', '2020-06-01')

insert into Logins (id, login_date) values ('7', '2020-06-02')

insert into Logins (id, login_date) values ('7', '2020-06-02')

insert into Logins (id, login_date) values ('7', '2020-06-03')

insert into Logins (id, login_date) values ('1', '2020-06-07')

insert into Logins (id, login_date) values ('7', '2020-06-10')

表结构

表 Accounts:

+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
id 是该表主键。
该表包含账户 id 和账户的用户名。

表 Logins:

+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| login_date | date |
+---------------+---------+
该表无主键, 可能包含重复项。
该表包含登录用户的账户 id 和登录日期. 用户也许一天内登录多次。

结果表格式如下例所示:

Accounts 表:
+----+----------+
| id | name |
+----+----------+
| 1 | Winston |
| 7 | Jonathan |
+----+----------+

Logins 表:
+----+------------+
| id | login_date |
+----+------------+
| 7 | 2020-05-30 |
| 1 | 2020-05-30 |
| 7 | 2020-05-31 |
| 7 | 2020-06-01 |
| 7 | 2020-06-02 |
| 7 | 2020-06-02 |
| 7 | 2020-06-03 |
| 1 | 2020-06-07 |
| 7 | 2020-06-10 |
+----+------------+

Result 表:
+----+----------+
| id | name |
+----+----------+
| 7 | Jonathan |
+----+----------+
id = 1 的用户 Winston 仅仅在不同的 2 天内登录了 2 次, 所以, Winston 不是活跃用户.
id = 7 的用户 Jonathon 在不同的 6 天内登录了 7 次, , 6 天中有 5 天是连续的, 所以, Jonathan 是活跃用户.

方法1

select distinct a.id,a.name from accounts a join
(select id,datediff(lead(login_date,4)over(partition by id order by login_date),login_date) as diff
from (select distinct id,login_date from logins) a) c
on a.id=c.id
where c.diff=4
order by id

1.datediff(date1,date2) 返回起始时间 date1 和结束时间 date2 之间的天数。返回 date1-date2 后的值。还有一个timestampdiff() 返回值是正好相反的。
https://blog.csdn.net/liguangix/article/details/80243197
2.lead(arg1, arg2) arg1表示列名,arg2表示向后行偏移量,默认为1。 当找不到值时返回null 。lag 向前,lead 向后。

方法2

select distinct a.id,a.name from accounts a 
join(
select id,login_date,
date_sub(login_date,interval row_number()over(partition by id order by login_date) day) as diff
from (select distinct id,login_date from logins) a)aa
on a.id=aa.id
group by a.id,aa.diff
having count(*)>=5
order by a.id

1.date_sub()函数从日期减去指定的时间间隔。DATE_SUB(OrderDate,INTERVAL 2 DAY)
2.row_number()12345
dense_rank()122345
rank()1224

2. #180连续出现的数字

链接:https://leetcode-cn.com/problems/consecutive-numbers
编写一个 SQL 查询,查找所有至少连续出现三次的数字。
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
例如,给定上面的 Logs 表, 1 是唯一连续出现至少三次的数字。

+-----------------+
| ConsecutiveNums |
+-----------------+
| 1 |
+-----------------+

Create table If Not Exists Logs (Id int, Num int)
Truncate table Logs
insert into Logs (Id, Num) values ('1', '1')
insert into Logs (Id, Num) values ('2', '1')
insert into Logs (Id, Num) values ('3', '1')
insert into Logs (Id, Num) values ('4', '2')
insert into Logs (Id, Num) values ('5', '1')
insert into Logs (Id, Num) values ('6', '2')
insert into Logs (Id, Num) values ('7', '2')

方法1

select distinct num as ConsecutiveNums from(
select id,num,
lead(num,1)over(order by id) as lead_1,
lead(num,2)over(order by id) as lead_2
from logs )aa
where aa.lead_1=num and aa.lead_2=num

方法2

select distinct num as ConsecutiveNums from(
select id,num,id+1-row_number()over(partition by num order by id)as diff
from logs)aa
group by num,diff
having count(*)>=3 

力扣给的测试样例里边有一个序号从0开始的,所以id+1保证不是负数

3.# 601. 体育馆的人流量

链接:https://leetcode-cn.com/problems/human-traffic-of-stadium
编写一个 SQL 查询以找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。返回按 visit_date 升序排列的结果表。
表:Stadium
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| visit_date | date |
| people | int |
+---------------+---------+
visit_date 是表的主键
每日人流量信息被记录在这三列信息中:序号 (id)、日期 (visit_date)、 人流量 (people)
每天只有一行记录,日期随着 id 的增加而增加

查询结果格式如下所示。
Stadium table:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 1 | 2017-01-01 | 10 |
| 2 | 2017-01-02 | 109 |
| 3 | 2017-01-03 | 150 |
| 4 | 2017-01-04 | 99 |
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-09 | 188 |
+------+------------+-----------+

Result table:

id visit_date people
5 2017-01-05 145
6 2017-01-06 1455
7 2017-01-07 199
8 2017-01-09 188

id 为 5、6、7、8 的四行 id 连续,并且每行都有 >= 100 的人数记录。
请注意,即使第 7 行和第 8 行的 visit_date 不是连续的,输出也应当包含第 8 行,因为我们只需要考虑 id 连续的记录。
不输出 id 为 2 和 3 的行,因为至少需要三条 id 连续的记录。

Create table If Not Exists stadium (id int, visit_date DATE NULL, people int)
Truncate table stadium
insert into stadium (id, visit_date, people) values ('1', '2017-01-01', '10')
insert into stadium (id, visit_date, people) values ('2', '2017-01-02', '109')
insert into stadium (id, visit_date, people) values ('3', '2017-01-03', '150')
insert into stadium (id, visit_date, people) values ('4', '2017-01-04', '99')
insert into stadium (id, visit_date, people) values ('5', '2017-01-05', '145')
insert into stadium (id, visit_date, people) values ('6', '2017-01-06', '1455')
insert into stadium (id, visit_date, people) values ('7', '2017-01-07', '199')
insert into stadium (id, visit_date, people) values ('8', '2017-01-09', '188')

方法1

select id,visit_date,people from(
select id,visit_date,people,
lead(people,1)over(order by id) as ld_1,
lead(people,2)over(order by id) as ld_2,
lag(people,1)over(order by id) as lg_1,
lag(people,2)over(order by id) as lg_2
from stadium )aa
where 
aa.people>=100 and (
(aa.ld_1>=100 and aa.ld_2>=100)or(aa.lg_1>=100
and aa.lg_2>=100)or( aa.lg_1>=100 and aa.ld_1>=100))
order by visit_date

这个和上一道的区别在于,上一道只是要求算出连续的那个数,这道题要求把所有连续的行都列出来。所以这道需要取出每行上下共5行的记录,因为所求的记录可能位于中间收尾和末位。

#603. 连续空余座位

几个朋友来到电影院的售票处,准备预约连续空余座位。
你能利用表 cinema ,帮他们写一个查询语句,获取所有空余座位,并将它们按照 seat_id 排序后返回吗?

seat_id free
1 1
2 0
3 1
4 1
5 1

对于如上样例,你的查询语句应该返回如下结果。

seat_id
3
4
5
Create table If Not Exists cinema (seat_id int primary key auto_increment, free bool)
Truncate table cinema
insert into cinema (seat_id, free) values ('1', '1')
insert into cinema (seat_id, free) values ('2', '0')
insert into cinema (seat_id, free) values ('3', '1')
insert into cinema (seat_id, free) values ('4', '1')
insert into cinema (seat_id, free) values ('5', '1')

方法

select distinct seat_id
from(
select seat_id,
lead(seat_id,1)over(order by seat_id) as ld1,
lag(seat_id,1)over(order by seat_id) as lg1
from cinema
where free=1)aa
where seat_id=ld1-1 or seat_id=lg1+1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容