sql 语言 groupBy 分组统计时间段解决方案 
                                                    
                        
                    
                    
  
                    
                    记录一下数据统计时遇到的问题和解决方案
先贴完整的效果
问题一 GroupBy数据不是每天连续的
统计图是关于某段时间内,每年/每月/每周的微博数量的折线图。数据为连续不断的,但现实的情况中数据库里的数据不可能是连续的,情况如下

数据中4号 ~ 7号的时间段没有返回,我们理想中的返回格式是补全没有的日期,然后在这个日期对应的数量字段填0。
在网上google了一下,解决方案是新建一张自期表做主表,左联要统计的表,
CREATE TABLE num (i int);-- 创建一个表用来储存0-9的数字
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);-- 生成0-9的数字,方便以后计算时间
CREATE TABLE  if not exists calendar(datelist date); -- 生成一个存储日期的表,datalist是字段名
-- 这里是生成并插入日期数据
INSERT INTO calendar(datelist) SELECT
    adddate(
        (   -- 这里的起始日期,你可以换成当前日期
            DATE_FORMAT("2016-1-1", '%Y-%m-%d') 
        ),
        numlist.id
    ) AS `date`
FROM
    (
        SELECT
            n1.i + n10.i * 10 + n100.i * 100 + n1000.i * 1000+ n10000.i * 10000 AS id
        FROM
            num n1
        CROSS JOIN num AS n10
        CROSS JOIN num AS n100
        CROSS JOIN num AS n1000
        CROSS JOIN num AS n10000
    ) AS numlist;
运行sql语句后,请删除num表
这个时间我们拿到了日期表,用日期表做主表,左联一下就能解决问题一

问题二 使用了left join,where是针对左表,但左表是日期表,那如何做业务表上的条件限制
原因分析:
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户;
where条件是在临时表生成好后,再对临时表进行过滤的条件;
因此:where 条件加上,已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
解决方案是把限制条件放在on后面
select a.*,b.*
from table1 a
left join table2 b on b.X=a.X and XXX
结论:
where后面:是先连接然生成临时查询结果,然后再筛选
on后面:先根据条件过滤筛选,再连 生成临时查询结果
结语
水平有限,关于补0的那个问题其实还想到查询出来用php循环补全日期和补0,但是业务上有很多处要用到这个,用php的话代码量很多,所以了新建日期表这个方案,如果有好的方案希望大家贴上来,多多交流。
本作品采用《CC 协议》,转载必须注明作者和本文链接
          
            
          
          
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: