目录
题目链接(无_力扣VIP_略过)
- 链接: 15分钟没思路建议直接看答案
一.读题(建议使用这种表结构_数据对比看)
__________________________________________
题目SQL Schema建表语句_数据
Create table If Not Exists UserActivity (username varchar(30), activity varchar(30), startDate date, endDate date)
Truncate table UserActivity
insert into UserActivity (username, activity, startDate, endDate) values ('Alice', 'Travel', '2020-02-12', '2020-02-20')
insert into UserActivity (username, activity, startDate, endDate) values ('Alice', 'Dancing', '2020-02-21', '2020-02-23')
insert into UserActivity (username, activity, startDate, endDate) values ('Alice', 'Travel', '2020-02-24', '2020-02-28')
insert into UserActivity (username, activity, startDate, endDate) values ('Bob', 'Travel', '2020-02-11', '2020-02-18')
二.答案_一图解
一图解__可只需看此
答案
-- 方法1
with a1 as (
-- 从useractivity表中选择所有列
select *,
-- 计算每个用户名的活动总数
count(*) over (partition by username) as c_u,
-- 根据活动开始日期对每个用户名的活动进行排序并分配排名
dense_rank() over (partition by username order by startDate desc) as dr
from useractivity
/*group by username, activity, startDate, endDate*/ -- 这里是一个注释的分组语句,可能在调试时用到
) -- 这里注释,是因为一开始题目说 该表可能有重复的行, 所以这里加上了group by语句,以计算准确的count(*)
-- 从临时表a1中选择用户名、活动、开始日期和结束日期 -- 但提交发现不需要,总之严谨为好!!!!!!!!!!!!!!
select username, activity, startDate, endDate
from a1
-- 过滤条件:选择活动总数为1的用户名,或排名为2的活动
where c_u = 1 or dr = 2;
-- 方法2
-- 从useractivity表中选择活动,使用别名u1和u2进行自连接
select u1.username, u1.activity, u1.startDate, u1.endDate
from useractivity u1
join useractivity u2
on u1.username = u2.username -- 连接条件:根据用户名进行连接
-- 按用户名、活动的开始日期和结束日期进行分组
group by u1.username, u1.startdate, u1.activity, u1.enddate
-- 过滤条件:满足条件的记录将被选择
having sum(u1.startdate < u2.startdate) = 1 or count(1) = 1;
-- 这里的条件表示:选择活动开始日期在至少一个活动之后的记录,或者只存在1个活动的用户
------------------------------------------------------------------------------
1. 方法分析流程图
方法1流程图
方法2流程图
2. 难点分析
- 窗口函数的使用:在方法1中,使用了窗口函数
count(*) over (partition by username)
和dense_rank() over (partition by username order by startDate desc)
来计算每个用户的活动总数和对活动进行排序。 - 自连接的使用:在方法2中,通过自连接
useractivity u1 join useractivity u2 on u1.username = u2.username
来比较同一用户的不同活动。 - 过滤条件的设置:在两种方法中,都需要设置合适的过滤条件来选择最近第二次的活动或只有一个活动的用户。
3. 关键总结
- 窗口函数:用于在查询结果集中执行聚合计算和排序,而不需要使用子查询或临时表。
- 自连接:用于将表与自身进行连接,以比较或关联同一表中的行。
- 过滤条件:用于从查询结果集中选择满足特定条件的行。
- 分组和聚合:用于对查询结果集进行分组,并执行聚合计算,如计数、求和等。