首先描述一下现状,目前有两张表
一张表 tb_stat_lord 统计用户的 注册时间,快速登陆时间,绑定账户时间,表结构如下
+----+-----+-------+---------------------+---------------------+---------------------+
| id | sid | lid | regtime | fasttime | bindtime |
+----+-----+-------+---------------------+---------------------+---------------------+
| 1 | 0 | 20001 | 0000-00-00 00:00:00 | 2014-12-25 10:13:47 | 0000-00-00 00:00:00 |
| 2 | 0 | 20002 | 2015-01-01 10:25:56 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
| 3 | 0 | 20003 | 2015-01-11 10:11:31 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
+----+-----+-------+---------------------+---------------------+---------------------+
另一张表 tb_stat_daily 统计用户每天的登陆情况,表结构如下
+----+-----+-------+------------+------------+------------+--------+------------+
| id | sid | lid | logintimes | timelength | loginscene | signin | time |
+----+-----+-------+------------+------------+------------+--------+------------+
| 1 | 0 | 20001 | 0 | 0 | 0 | 0 | 2015-01-06 |
| 2 | 0 | 20001 | 0 | 0 | 0 | 0 | 2015-01-09 |
| 3 | 0 | 20002 | 0 | 0 | 0 | 0 | 2015-01-11 |
| 4 | 0 | 20002 | 0 | 0 | 0 | 0 | 2015-01-12 |
| 5 | 0 | 20003 | 0 | 0 | 0 | 0 | 2015-01-12 |
+----+-----+-------+------------+------------+------------+--------+------------+
再描述一下需求,这是一个游戏项目,这两张表属于统计数据库,用户注册以后7天内没有登陆,但是后来又再次登陆,需求是想统计出这部分用户数量。
当我没有想到正确方法的时候,我始终很难理清思路,首先确定的是表连接,tb_stat_daily 和 tb_stat_lord 是N:1的关系,我按照时间去查询,有一个用户,7日内登录过,7日后再登陆,还是会被我查出来,这条数据其实是不符合要求的,所以说这让我曾一度否定 表连接查询。我也曾想过通过程序来控制,首先查找记录用户编号,用户注册时间,写循环再去查 tb_stat_daily,这里还是会碰到同一用户有多条数据的尴尬场景,不管程序我把这些表数据分离的再细,我始终很难沿着我的一个想法进行下去。最终不得不搁浅...
这时恰逢周末,半睡半醒中,我又想到了这个问题,有了新的突破。我想到我以前的一个很小的需求,同一条数据插入多条,我只想保留其中最早的一条,其实当初这个问题并非急需,当初我也没有找到解决方案。它为什么会对我这个棘手的问题有帮助呢?我为什么不取 tb_stat_daily 的用户出现的第一条数据呢?如此以来,tb_stat_daily 和 tb_stat_lord 就是 1:1 的关系了,tb_stat_daily 中的时间去和 tb_stat_lord 中的注册时间去比较,比注册时间大7天不正是我想要的数据吗?想到这里,我就已经知道这个方法是可行的,接着就醒了,激动的再也睡不着了。
首先我想查出 tb_stat_daily 中不重复数据
SELECT * FROM tb_stat_daily GROUP by lid;
接下来就要连接查询了,若是想看更详细的MYSQL各种连接方式,请移步:http://huaxia524151.iteye.com/blog/1423614
SELECT * FROM tb_stat_daily AS T1 INNER JOIN tb_stat_lord AS T2 WHERE T1.lid = T2.lid;
怎样放组合这个SQL语句呢,好像只能这样写,这次顺便增加上判定条件吧(注意 WHERE 和 GROUP的顺序,AND 和 OR组合使用加括号的方式)
SELECT * FROM tb_stat_daily AS T1 INNER JOIN tb_stat_lord AS T2 WHERE T1.lid = T2.lid AND (TO_DAYS(time) - TO_DAYS(regtime) > 7 OR TO_DAYS(time) - TO_DAYS(fasttime)) GROUP BY T1.lid;
这样以来,就满足需求了...