编写一个SQL查询,查找至少连续出现三次的所有数字。
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+

【1】sql server优质解法:

【1.1】连续3次以上出现的数字

CREATE TABLE #A
(
id INT IDENTITY(1,1),
val INT
)
INSERT INTO #A(val) VALUES(1),(1),(1),(1),(2),(2),(3),(4),(4),(4),(4),(4)
INSERT INTO #A(val) VALUES(1)
select * from #A
SELECT val,MIN(id) AS minid,MAX(id) AS maxid, COUNT(1) AS cmd FROM
(
SELECT *,id-ROW_NUMBER() OVER( PARTITION BY val ORDER BY id ) AS idx FROM #A ) S GROUP BY val,idx


【1.2】连续出现的日期:(比如,想要查询连续登录超过3天的用户)

CREATE TABLE #b
(
id INT IDENTITY(1,1),
userid INT,
login_time datetime
)
INSERT INTO #b(userid,login_time)VALUES(101,''),(102,'')
INSERT INTO #b(userid,login_time)VALUES(102,'')
INSERT INTO #b(userid,login_time)VALUES(101,''),(102,'')
INSERT INTO #b(userid,login_time)VALUES(101,''),(102,'')
INSERT INTO #b(userid,login_time)VALUES(101,''),(102,'')
INSERT INTO #b(userid,login_time)VALUES(101,'')
INSERT INTO #b(userid,login_time)VALUES(101,'')
INSERT INTO #b(userid,login_time)VALUES(101,'') SELECT * FROM #b ORDER BY userid ,login_time --解答
SELECT userid, MIN(login_time) AS StartDate, MAX(login_time) AS EndDate, COUNT(1) AS DayCount
FROM (
SELECT userid
,login_time
,DATEADD(dd, -ROW_NUMBER() OVER ( PARTITION BY userid ORDER BY login_time), login_time) AS Grp
FROM #b
) AS T
GROUP BY userid, [Grp]
ORDER BY 1

【2】mysql办法解决

【2.1】连续时间(比如,想要查询连续登录超过3天的用户)

(8.0以前,8.0以后可以用上述sql server 办法)


 测试代码

-- 测试数据代码
CREATE TABLE b
(
id INT primary key auto_increment,
userid INT,
login_time datetime
);
-- select * from b order by userid;
INSERT INTO b(userid,login_time) VALUES(101,''),(102,'');
INSERT INTO b(userid,login_time) VALUES(101,''),(102,'');
INSERT INTO b(userid,login_time) VALUES(101,''),(102,'');
INSERT INTO b(userid,login_time) VALUES(101,''),(102,'');
INSERT INTO b(userid,login_time) VALUES(101,''),(102,'');
INSERT INTO b(userid,login_time) VALUES(101,'');
INSERT INTO b(userid,login_time) VALUES(101,'');
INSERT INTO b(userid,login_time) VALUES(101,'');
INSERT INTO b(userid,login_time) VALUES(101,'');
INSERT INTO b(userid,login_time) VALUES(101,'');
INSERT INTO b(userid,login_time) VALUES(101,'');
INSERT INTO b(userid,login_time) VALUES(102,'');

插入后生成的测试表数据: 

    

实现代码:

select userid,min(login_time) min_date,max(login_time) max_date,count(1) as day_count
from (
select b.*,
date_add(login_time,interval -if(@group_str=userid,@num:=@num+1,@num:=1) day) as login ,
@group_str:=userid as temp
from b cross join (select @num:=0,@group_str=-1) t
order by b.userid,login_time ) t
group by userid,login 结果:


【2.2】连续3次以上出现的数字

  强烈推荐解法三

编写一个SQL查询,查找至少连续出现三次的所有数字。
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
-- 建表
create table Logs(id int primary key auto_increment,num int); -- 造数据
INSERT INTO Logs(num) VALUES(1),(1),(1),(1),(2),(2),(3),(4),(4),(4),(4),(4),(1);

mysql解法:

这道题给了我们一个Logs表,让我们找Num列中连续出现相同数字三次的数字,那么由于需要找三次相同数字,所以我们需要建立三个表的实例.
我们可以用l1分别和l2, l3内交,l1和l2的Id下一个位置比,l1和l3的下两个位置比,然后将Num都相同的数字返回即可:

解法一:

SELECT DISTINCT l1.Num FROM Logs l1
JOIN Logs l2 ON l1.Id = l2.Id - 1
JOIN Logs l3 ON l1.Id = l3.Id - 2
WHERE l1.Num = l2.Num AND l2.Num = l3.Num;

  

   

下面这种方法没用用到Join,而是直接在三个表的实例中查找,然后把四个条件限定上,就可以返回正确结果了:

解法二:

SELECT DISTINCT l1.Num FROM Logs l1, Logs l2, Logs l3
WHERE l1.Id = l2.Id - 1 AND l2.Id = l3.Id - 1
AND l1.Num = l2.Num AND l2.Num = l3.Num;

  再来看一种画风截然不同的方法,用到了变量count和pre,分别初始化为0和-1,然后需要注意的是用到了IF语句,MySQL里的IF语句和我们所熟知的其他语言的if不太一样,相当于我们所熟悉的三元操作符a?b:c,若a真返回b,否则返回c,具体可看这个帖子。那么我们先来看对于Num列的第一个数字1,pre由于初始化是-1,和当前Num不同,所以此时count赋1,此时给pre赋为1,然后Num列的第二个1进来,此时的pre和Num相同了,count自增1,到Num列的第三个1进来,count增加到了3,此时满足了where条件,t.n >= 3,所以1就被select出来了,以此类推遍历完整个Num就可以得到最终结果:

解法三:

SELECT DISTINCT Num FROM (
SELECT Num, @count := IF(@pre = Num, @count + 1, 1) AS n, @pre := Num
FROM Logs, (SELECT @count := 0, @pre := -1) AS init
) AS t WHERE t.n >= 3;

  


查找至少连续出现三次的所有数字/连续3天的日期【LeetCode】的更多相关文章

  1. 递推,求至少连续放置三个U的危险组合

    UVA580-Critical Mass 题意 有两种方块,L和U,有至少三个连续的U称为危险组合,问有多少个危险组合 solution: 至少这个概念比较难求 ,所以转化为(1ll<<n ...

  2. 大数据学习day25------spark08-----1. 读取数据库的形式创建DataFrame 2. Parquet格式的数据源 3. Orc格式的数据源 4.spark_sql整合hive 5.在IDEA中编写spark程序(用来操作hive) 6. SQL风格和DSL风格以及RDD的形式计算连续登陆三天的用户

    1. 读取数据库的形式创建DataFrame DataFrameFromJDBC object DataFrameFromJDBC { def main(args: Array[String]): U ...

  3. 剑指Offer(三十七):数字在排序数组中出现的次数

    剑指Offer(三十七):数字在排序数组中出现的次数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.n ...

  4. 连续子数组的最大乘积及连续子数组的最大和(Java)

    1. 子数组的最大和 输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.例如数组:arr[]={1, 2, 3, -2, ...

  5. 二维动态规划&&二分查找的动态规划&&最长递增子序列&&最长连续递增子序列

    题目描述与背景介绍 背景题目: [674. 最长连续递增序列]https://leetcode-cn.com/problems/longest-continuous-increasing-subseq ...

  6. opencv学习之路(24)、轮廓查找与绘制(三)——凸包

    一.简介 二.绘制点集的凸包 #include<opencv2/opencv.hpp> using namespace cv; void main() { //---绘制点集的凸包 Mat ...

  7. 编写一个程序,从标准输入中读取若干string对象并查找连续重复出现的单词。所谓连续重复出现的意思是:一个单词后面紧跟着这个单词本身。要求记录连续重复出现的最大次数以及对应的单词

    #include<iostream> #include<string> #include<vector> using namespace std; int main ...

  8. python 练习题1--打印三位不重复数字

    题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 程序源代码 ...

  9. 【控制系统数字仿真与CAD】实验三:离散相似法数字仿真

    一.实验目的 1. 了解离散相似法的基本原理 2. 掌握离散相似法仿真的基本过程 3. 应用离散相似法仿真非线性系统 4. MATLAB实现离散相似法的非线性系统仿真 5. 掌握SIMULINK仿真方 ...

随机推荐

  1. Selenium操作之滚动条

    在用Selenium做UI自动化时,经常会遇到有些元素找不到之类的问题,但是自己的代码并没有错,元素就是找不到,这是为什么呢?原因很简单,由于页面内容较多,有些内容需要下拉滚动条才会显示,这里介绍一种 ...

  2. hibernate 在web.xml中配置的作用

    1. <filter>     <filter-name>Spring character encoding filter</filter-name>     &l ...

  3. Jquery学习笔记(3)--注册验证

    嗯哼,验证用户名,密码,重复密码,手机号,邮箱.提交时全部进行验证,通过才跳转. <!DOCTYPE html> <html lang="en"> < ...

  4. JavaScript 数组-Array的方法总结

    JavaScript中的Array类型是经常用到的,Array类型也提供了很多方法能实现我们需求,下面我们来总结一下 一.创建Array的方法 1.使用Array构造函数 var colors=new ...

  5. 清空oracle数据库

    在开发过程中,可能经常需要重新初始化数据库,在初始化之前,我们肯定希望不再有以前的老表.存储过程等用户对象,用下面的教本就可以做到这一点: BEGIN FOR rec IN (SELECT objec ...

  6. git三种模式及常用命令

    Git的三种重要模式,分别是已提交.已修改.已暂存. 已提交(committed):表示数据文件已经顺利提交到Git数据库中. 已修改(modified):表示数据文件已经被修改,但未被保存到Git数 ...

  7. 【Mac + Appium + Python3.6学习(六)】之安装Android模拟器(Genymotion)并运行模拟器进行自动化

    环境: MacOS:10.13.6 Virtualbox:5.2.22 Genymotion:genymotion-2.12.2 本文Virtualbox.Genymotion下载地址: 链接:htt ...

  8. vb 定时执行php程序

    托盘模块 Option Explicit Public Const NIF_ICON = &H2 Public Const NIF_MESSAGE = &H1 Public Const ...

  9. Java实现验证码的制作

    验证码概述 为什么使用验证码? 验证码(CAPTCHA)是一种全自动程序.主要是为了区分“进行操作的是不是人”.如果没有验证码机制,将会导致以下的问题: 对特定网站不断进行登录,破解密码: 对某个网站 ...

  10. java基础-集合笔记

    Iterator(foreach) 遍历时只能通过iterator去删除(添加)元素,不能直接通过集合对象删除或添加元素 Set HashSet底层是一个HashMap HashSet添加元素,先判断 ...