1369. 获取最近第二次的活动

题目链接(无_力扣VIP_略过)

一.读题(建议使用这种表结构_数据对比看)

__________________________________________

在这里插入图片描述

题目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流程图
从UserActivity表中选择所有列 计算每个用户名的活动总数和根据活动开始日期对每个用户名的活动进行排序并分配排名 创建临时表a1存储上述计算结果 从临时表a1中选择用户名、活动、开始日期和结束日期 过滤条件:选择活动总数为1的用户名,或排名为2的活动
方法2流程图
从UserActivity表中选择活动,使用别名u1和u2进行自连接 连接条件:根据用户名进行连接 按用户名、活动的开始日期和结束日期进行分组 过滤条件:满足条件的记录将被选择 选择活动开始日期在至少一个活动之后的记录,或者只存在1个活动的用户

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. 关键总结

  • 窗口函数:用于在查询结果集中执行聚合计算和排序,而不需要使用子查询或临时表。
  • 自连接:用于将表与自身进行连接,以比较或关联同一表中的行。
  • 过滤条件:用于从查询结果集中选择满足特定条件的行。
  • 分组和聚合:用于对查询结果集进行分组,并执行聚合计算,如计数、求和等。

创作不易,点赞留意,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十六ᵛᵃᵉ

停船靠岸_愿君通关

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值