遇到连续问题怎么办?

该博客详细解析了如何使用SQL查询用户登录记录表,找出2021年每个月连续2天登录的用户。首先通过row_number()窗口函数对用户每月登录顺序进行标记,然后计算连续登录天数,最后筛选出连续登录天数大于等于2的用户。内容涵盖了SQL子查询、窗口函数、日期函数以及分组统计等技术。
摘要由CSDN通过智能技术生成

有一张“用户登陆记录表”,包含两个字段:用户id、日期。

 

【问题】查询2021年每个月,连续2天都有登陆的用户名单。

【解题步骤】

1.思路

怎么能知道连续登陆用户呢?

首先对用户连续登陆进行标记

 select 用户id,日期, 
        month(日期) as 月,
        day(日期) as 日,
row_number() over (partition by month(日期), 用户id order by 日期) as 每个月登陆顺序

 from 用户登陆记录表
 where 日期 between '2021-01-01' and '2021-12-31';

查询结果(把这个SQL记为子查询t1):

用“天”和“每个月登陆顺序”的差值来做标记:

 select 月,日期,用户id,
        (日 - 每个月登陆顺序) as 标记
 from t1;

查询结果(把这个SQL记为子查询t2):

3. 汇总分析

1)分组汇总:查询每个月,每个用户,每一次连续登陆的天数。

也就是分组(group by 月,用户id,标记),统计(对分组后每个组计数就是连续登陆的天数 count)

1 select 月,用户id,标记,
2        count(*) as 连续登陆天数
3 from t2
4 group by 月,用户id,标记;

查询结果(把这个SQL记为子查询t3):

2)在上一步的基础上,用where子句筛选出连续2天都有登陆的用户:

1 select distinct 月,用户id
2 from t3
3 where 连续登陆天数 >= 2;

到这里我们已经得到了题目要求的结果,可以把前面的子查询t1、t2、t3代入上面的SQL语句,就得到了最终的SQL:

1 select distinct 月,用户id
2 from
3 (select 月,用户id,标记,
4        count(*) as 连续登陆天数
5 from
6 (select 月,日期,用户id,
7        (日 - 每个月登陆顺序) as 标记
8 from
9 (select 用户id,日期,
10        month(日期) as 月,
11        day(日期) as 日,
12        row_number() over (partition by month(日期), 用户id 
13                           order by 日期) as 每个月登陆顺序
14 from 用户登陆记录表
15 where 日期 between '2021-01-01' and '2021-12-31'
16 ) as t1
17 ) as t2
18 group by 月,用户id,标记
19 ) as t3
20 where 连续登陆天数 >= 2;

 

查询结果:

【本题考点】

1.考查对复杂问题的拆解能力,可以使用逻辑树分析方法,将一个复杂问题拆解为可以解决的子问题,然后逐步解决

2.对子查询的应用,当一个复杂问题需要多个子问题来解决时候,可以把每个子问题写成一个子查询

3.考查对常见函数的了解:month()、day()、count();

4.考查对窗口函数的应用,窗口函数能解决的几类典型问题要能牢记;

【举一反三】

查询2021年每个月,连续5天都有登陆的用户数。

与原题的区别在于:

1)“连续2天”变成了“连续5天”:对最后的where条件进行修改;

2)查询“用户名单”变成了“用户数”:用group by按月分组,然后统计用户数和count(distinct 用户id)。

 
1 select 月,
2        count(distinct 用户id) as 连续5天登陆的用户数
3 from
4 (select 月,用户id,标记,
5        count(*) as 连续登陆天数
6 from
7 (select 月,日期,用户id,
8        (日 - 每个月登陆顺序) as 标记
9 from
10 (select 用户id,日期,
11        month(日期) as 月,
12        day(日期) as 日,
13        row_number() over (partition by month(日期), 用户id 
14                           order by 日期) as 每个月登陆顺序
15 from 用户登陆记录表
16 where 日期 between '2021-01-01' and '2021-12-31'
17 ) as t1
18 ) as t2
19 group by 月,用户id,标记
20 ) as t3
21 where 连续登陆天数 >= 5
22 group by 月;

 

 

 

 

 

 

 

连续信号不能直接进行FFT计算,因为FFT是一种离散傅里叶变换,需要对离散信号进行频域分析。因此,需要将连续信号离散化,然后再进行FFT计算。具体来说,连续信号频谱分析的流程如下: 1. 将连续信号x(t)进行采样,得到离散信号x(n),其中n为采样点的序号,采样频率为Fs。 2. 对离散信号x(n)进行FFT计算,得到离散频域采样值X(k),其中k为频域采样点的序号。FFT计算复杂度为NlogN,其中N为采样点数。 3. 将离散频域采样值X(k)进行插值,得到连续频域采样值X(f),其中f为频率。插值可以采用线性插值、样条插值等方法。 4. 对连续频域采样值X(f)进行频谱分析,例如计算功率谱密度、滤波等。 在这个流程中,可能会遇到以下问题: 1. 采样定理问题:采样频率Fs必须满足Nyquist采样定理,即Fs≥2fmax,其中fmax为信号中最高频率成分的频率。如果采样频率过低,会导致信号的高频成分混叠到低频区域,使得频域分析结果不准确。 2. 插值问题:插值方法的选择会影响到频域分析结果的准确性和计算效率。线性插值简单快速,但精度较低;样条插值精度较高,但计算复杂度较高。 3. 计算精度问题:FFT计算过程中存在舍入误差,可能会影响到频域分析结果的精度。可以采用高精度计算方法、多次计算取平均等方法来提高计算精度。 4. 计算复杂度问题:FFT计算复杂度为NlogN,当采样点数较大时,计算复杂度会很高,可能需要采用并行计算、GPU加速等方法来提高计算效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风月の铁锤

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值