暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

单挑力扣(LeetCode)SQL题:180. 连续出现的数字(难度:中等)

跟强哥学SQL 2022-09-12
676
题目:180. 连续出现的数字
(通过次数124,862 | 提交次数258,838,通过率48.24%)

    表:Logs
    +-------------+---------+
    | Column Name | Type |
    +-------------+---------+
    | id | int |
    | num | varchar |
    +-------------+---------+
    id 是这个表的主键。


    编写一个 SQL 查询,查找所有至少连续出现三次的数字。
    返回的结果表中的数据可以按 任意顺序 排列。
    查询结果格式如下面的例子所示:


    示例 1:
    输入:
    Logs 表:
    +----+-----+
    | Id | Num |
    +----+-----+
    | 1 | 1 |
    | 2 | 1 |
    | 3 | 1 |
    | 4 | 2 |
    | 5 | 1 |
    | 6 | 2 |
    | 7 | 2 |
    +----+-----+
    输出:
    Result 表:
    +-----------------+
    | ConsecutiveNums |
    +-----------------+
    | 1 |
    +-----------------+
    解释:1 是唯一连续出现至少三次的数字。


    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/consecutive-numbers

      #测试数据
      Create table If Not Exists Logs (id int, num int);


      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 (idnumvalues ('6''2');

      解题思路:
      这又是一个求连续次数及连续区间的问题。
      单挑力扣(LeetCode)SQL题:1285. 找到连续区间的开始和结束数字(难度:中等)中,我提到,连续区间一般有以下3个特性:
      第一种特性:一个有序的集市,错位相减,可以得到区间的开始值和结束值;
      第二种特性:如果一个数字是一个区间的开始值,那么这个数字-1一定不在集合中;相应的,如果一个数字是一个区间的结束值,那么这个数字+1一定不在集合中;
      第三种特性:一个有序的集合,如果某几个值是连续的,那么这几个值-它的序号一定是相同的;
      因为本次判断是否连续的要求是:连续相同的值。那么,如果基于第三种特性直接计算,是不行的。
      我们可以使用开窗函数,在组内构建一个序号,这样就可以保证“值-它的序号”是相同的了。
      下面参考SQL的方法二,就是基于这种特性。
      当然,我们也可以基于第二种特性,计算出每个区间的开始值和结束值,然后再计算出连续的个数。
      下面参考SQL的方法一,就是基于这种特性。
      参考SQL:
        #方法1
        select
        distinct b.num ConsecutiveNums
        from (
        select
        a.num,
        (row_number() over (order by a.id asc) -
        row_number() over (partition by a.num order by a.id asc)) as series_id
        from logs a
        ) b
        group by b.num, b.series_id
        having count(1) >= 3;


        #方法2
        with tmp as (
        select
        a.id,a.num,
        row_number() over(order by a.id) rn
        from Logs a
        where (a.id,a.num) not in (select b.id+1,b.num from Logs b)
        or (a.id,a.num) not in (select c.id-1,c.num from Logs c)
        )
        select
        a.num ConsecutiveNums
        from tmp a
        inner join tmp b
        on a.rn = b.rn-1
        and a.num = b.num
        and b.id - a.id >=2
        group by a.num;

        拯救你的PPT颜值,各大高校高颜值PPT模板免费领!
        API接口设计,这一点一定要注意!
        单挑力扣(LeetCode)SQL题:1709. 访问日期之间最大的空档期(难度:中等)
        文章转载自跟强哥学SQL,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论