一个有趣的 SQL 查询(查询7天连续登陆)

一个有趣的 SQL 查询

一个朋友有这样一个SQL查询需求: 
有一个登录表(tmp_test),包含用户ID(uid)和登录时间(login_time)。表结构如下:

*************************** 1. row ***************************
Field: uid
Type: int(10) unsigned
Null: NO
Key: MUL
Default: NULL
Extra:
*************************** 2. row ***************************
Field: login_time
Type: timestamp
Null: NO
Key: MUL
Default: 0000-00-00 00:00:00
Extra: 

问如何查询出所有在某一段时间内(如:2012-1-1至2012-1-17)连续7天都有登录的用户。

在写这个SQL时,发现一些很有意思东西,也许对大家写SQL有帮助,因此记录一下。

- 基本思路 Loop Join
  首先想到的思路是一个类似于Loop Join的方法:
  A. 取出2012-1-1到2012-1-11的每一条记录.
  B. 对取出的每一条记录,再去表中查询这个用户的接下来6天的记录。
     如果总数为6条记录,则满足连续7天的条件

- Range Join
  Loop Join的思路可以通过一个Join语句来实现。姑且称之为Range Join。通常join时,使用的都是
  等值join. 如果join列的值是唯一的,那么就是左表的一条记录对应右表的一条记录。而Range Join
  中,左表的一行数据对应右表的一个范围内的所有记录。

SQL 语句为:

SELECT DISTINCT t.uid FROM tmp_test AS t JOIN tmp_test AS t1
ON date(t.login_time) + 1 <= date(t1.login_time) AND
   date(t.login_time) + 7 > date(t1.login_time) AND
   t.uid = t1.uid
WHERE t.login_time BETWEEN ’2012-1-1 00:00:00′ AND ’2012-1-11 23:59:59′ AND
      t1.login_time >= ’2012-1-2′ AND t.login_time < ’2012-1-18′(可去掉)

- COUNT(DISTINCT)
  “计算连续7天”,可以通过GROUP BY分组和COUNT()来完成。因为一个用户在1天内可能会有多次登录,
  这里需要使用(COUNT DISTINCT). SQL 语句为:

GROUP BY t.login_time, t.uid
HAVING COUNT(DISTINCT date(t1.login_time))=6

- BIT_OR
  考虑到DISTINCT操作需要缓存数据,就想到了用bit逻辑运算(可能会效率高一些)。因为连续的七天
  与第一天的差分别为,1,2,3,4,5,6,7.可以分别用1-7bit位来表示。根据这个特点,可以对分组中
  的每一行进行或(|)运算.如果最后的值等于b’1111110′(6个1).那么就是连续的7天。这个办法可以
  避免DISTINC操作。没想到MySQL中真的有了bit操作的聚合函数。BIT_OR就是我们要用的。

http://www.oschina.net/question/28_41179?sort=default&p=1

时间: 09-22

一个有趣的 SQL 查询(查询7天连续登陆)的相关文章

一个有趣的SQL Server 层级汇总数据问题

看SQL Server大V宋大侠的博客文章,发现了一个有趣的sql server层级汇总数据问题. 具体的问题如下: parent_id emp_id emp_name total_amout     NULL 2 Andrew 200     2 1 Nancy 100     2 3 Janet 120     3 4 Michael 80     1 5 Robert 50     每个员工的总销售额=自己的销售额+其下级员工的总销售额,     比如:     Andrew = 200_

分享一个绿色版本 sql server 查询器,

首先感谢原作者 源码来原于网络 此查询器增加了一些功能, 可以高亮显示 导出sql 语句    可以把左边树型拖入脚本编辑器 http://pan.baidu.com/s/1dDjaSbn

数据库 将多条SQL语句查询的内容整合成为一个元组

1.情景再现 分类信息 住户 租户 快递 亲友访问 花苑 138 25 44 89 新城 34 150 78 34 以上的一张表中,假如要分别在两个住宅小区统计各类进出的人数,进出的类型可以分为是住户,租户,快递以及亲友访问四个类型. 但是实际的表设计中,住户以及租户是属于这个小区,可以直接统计出来,但是快递以及亲友访问则需要从进出记录查找. 换言之,就是表中的每个元组的数据是从多个表中查出来的,同时可能是用四条sql语句中查询出来的.使用如下表达: ①: select t.name as co

新建一个索引能够同时提升三条SQL的查询性能

如题 CREATE TABLE `score` (   `id` int(11) NOT NULL,   `studentid` int(11) NOT NULL,   `subjectid` int(11) NOT NULL,   `score` int(11) NOT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 新建一个索引能够同时提升三条SQL的查询性能 ALTER TABLE `score` AD

[转]一个用户SQL慢查询分析,原因及优化

来源:http://blog.rds.aliyun.com/2014/05/23/%E4%B8%80%E4%B8%AA%E7%94%A8%E6%88%B7sql%E6%85%A2%E6%9F%A5%E8%AF%A2%E5%88%86%E6%9E%90%EF%BC%8C%E5%8E%9F%E5%9B%A0%E5%8F%8A%E4%BC%98%E5%8C%96/ 问题描述 一个用户反映先线一个SQL语句执行时间慢得无法接受.SQL语句看上去很简单(本文描述中修改了表名和字段名):SELECT cou

SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比

原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比 今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章,自己添加了一些内容,做了简单的总结,这个语句还是第一次见到,学习了.我从简单到复杂地写,希望高手们不要见笑.下面的sql语句设计到三个表,表的内容我用txt文件复制进去,这里不妨使用上一个随笔介绍的建立端到端的package的方法将这些表导入到数据库中,具体的就不说了. 从这里下载文件employ

python 3 mysql sql逻辑查询语句执行顺序

python 3 mysql sql逻辑查询语句执行顺序 一 .SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <right_table> ON <join_condition> WHERE <where_condition> GROUP BY <group_by_list> HAVING <havin

SQL数据库查询方法

SQL数据库查询方法 简单查询: 一.投影 select * from 表名 select 列1,列2... from 表名 select distinct 列名 from 表名 二.筛选 select top 数字 列|* from 表名 (一)等值与不等值 select * from 表名 where 列名=值 select * from 表名 where 列名!=值 select * from 表名 where 列名>值 select * from 表名 where 列名<值 selec

mysql按年度、季度、月度、周、日SQL统计查询

说明 1 2 3 4 5 SELECT YEAR('2014-10-29')   //2014 SELECT MONTH('2014-10-29')  //10 SELECT DAY('2014-10-29')  //29 SELECT QUARTER('2014-10-29')  //4  季度 SELECT DAYOFWEEK('2014-10-29') //4  星期 一.年度查询查询本年度的数据 1 2 3 SELECT * FROM blog_article WHERE year( F