记一次SQL踩坑之旅


作为一个平时不太接触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;


    ,,,,,,土鳖啃蹄牛



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值