自学内容网 自学内容网

【力扣白嫖日记】180.连续出现的数字

前言

练习sql语句,所有题目来自于力扣(https://leetcode.cn/problemset/database/)的免费数据库练习题。

今日题目:

180.连续出现的数字
表:Logs

列名类型
idint
numvarchar

找出所有至少连续出现三次的数字。

返回的结果表中的数据可以按 任意顺序 排列。


我那不值一提的想法:

  • 首先梳理表内容,题干一共了一张表,记录了id和数字。
  • 其次分析需求,找出连续出现三次的数字
  • 要实现这个需求,需要满足三个条件
  • 第一个,id不同,num值相同
  • 第二个,id之间差值只能是1
  • 第三个,num的数量得大于等于3
  • 要同时满足上面三个条件,我们可以直接三个表连接
  • 第一个条件和第二个条件,s2.id - s1.id = 1 and s3.id - s2.id = 1 and s1.num = s2.num = s3.num
  • 第三个条件,因为是三个表连接,所以要至少得连续三个及以上的相同数字才能符合条件
select distinct s1.num as ConsecutiveNums
from Logs s1,Logs s2,Logs s3
where s1.num = s2.num 
and s2.num = s3.num
and s1.id + 1 = s2.id
and s2.id + 1 = s3.id

这个答案虽然能解决需求,但是我知道这解法只能解连续3个数连续的,如果有更多的就需要更多的表。于是我在neilsons的题解中学到了更高阶的方法。

  • 首先我们需要知道row_number函数,row_number函数用于为结果集中的行分配一个唯一的连续整数值,比如row_number() over(order by num) as series,就是对num进行排序,并且创建series列,里面对应了num从小到大的排序。
  • 对于这道题我们需要对原始数据进行编号,因为题干中并没有提到id是连续的:
select id,num,row_number() over(order by id) as series
from Logs

在这里插入图片描述

  • 其次我们需要对num进行分组排序
select id,num,row_number() over(partition by num order by id) as series
from Logs

在这里插入图片描述
在这里我们可以看到,只要数字连续相同,它在表中的序列-它第几次出现,是一个定值,也就是这样:

select id,num,row_number() over(order by id)-row_number() over(partition by num order by id) as series3
from Logs

在这里插入图片描述

  • 最后我们将其作为一个临时表,查询这个结果,group by num,series,使数量大于等于3,就能得到最终的结果:
select distinct num as ConsecutiveNums 
from 
(select id,num,
row_number() over(order by id) - row_number() over(partition by num order by id) as series
from Logs
) as a 
group by num,series
having count(*) >=3

引用:

https://leetcode.cn/problems/consecutive-numbers/solutions/21537/sql-server-jie-fa-by-neilsons


结果:

  • 三表连接
    在这里插入图片描述
  • row_number()
    在这里插入图片描述

总结:

能运行就行。



原文地址:https://blog.csdn.net/dkmaa/article/details/136302362

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!