作为一个平时不太接触SQL语句的程序员,平时对SQL的理解仅停留在简单的CRUD上。
什么SQL优化完全不知道怎么回事,,最近终于有机会自己需要自己的写SQL,中间的磕磕绊绊好不艰辛,特写文记录之
第一阶段
拥有数据:
表 record
col1 id 类型 INT
。。。
col13 date 类型 DATE TIME (是的这个表非常大,应该说设计的不是很好,不过我们这里先忽略这个问题 )
任务:
分别以年/月/日查询表RECORD的数据,按时间升序排列
解决方案:
好的,这个的我知道 用DATE_FORMATE来解析DATETIME就好 DATE_FORMATE(DATE,‘%Y-%m-%d’) = ‘YYYY-mm-dd' 就可以找出指定日期的记录了,那么要得到以月为单位的 2016年 record数量的统计数据对应的SQL语句就是
SELECT COUNT(*)
FROM rec_test
WHERE DATE_FORMAT(rec_time, '%Y') = '2016'
GROUP BY DATE_FORMAT(rec_time ,'%Y-%m');
(这里强调下DATE_FORMATE中的formate的大小写敏感的问题,比如%Y就是显示4为的年而 %y就只显示2为,对应的%m是用2位来显示月(需要补0) 而%M是以英文缩写的方式来显示月的,在传日期进行比较的话要注意的传入的字符串日期的格式和DATE_FORMATE中formate是否匹配)
来看些结果 虽然返回的是正确的 不过由于我们date并没有覆盖到全年,这样返回的值是没办法直接用的,(对的我们就想一条SQL解决问题,不要和我说再写条语语句返回对应的有效的日期,我不听 我不听)
第二阶段:
拥有数据:
同第一阶段
任务:
把没有数据的日期补0
解决方案:
那么用IFNULL行不行呢?当然不行!IFNULL可以把为NULL查询结果变为你指定的值,但是我们的查询结果没有数据的对应日期根本不存在行!!!哎。。。要是我们的record表平时没有数据日子也加一条NULL记录就好了。对的就是顺着这个思路想下去 造新表----表合并 ----- SQL JOIN !!!(如果你看完SQL相关书籍后 就没有确实写过SQL语句,这个语句的作用应该已经被你忘了 快往下看!)
设 左表LT 右表 RT
LEFT JOIN ON
以ON的后的表达式为匹配条件 返回 LT 并 (LT 交RT)
这样我们生成一个只包含每天日期的表mdate然后以它为LT record为RT 以日期一致为ON的匹配条件 来生成新表。这样在新表中来统计record的id数的时候,之前没有数据的日期就会为0!我们以为查询2017年2月份 中每天数据量的SQL语句为例
SELECT COUNT(rc.id)
FROM mdate AS mt
LEFT JOIN record AS rc
ON DATE_FORMAT(mt.date,'%Y-%m-%d') = DATE_FORMAT(rc.date,'%Y-%m-%d')
WHERE date_format(mt.date,'%Y-%m')='2017-02'
GROUP BY DATE_FORMAT(mt.date,'%Y-%m-%d') ORDER BY mt.date;
,,,,,,土鳖啃蹄牛