您的位置:首页 > 博客中心 > 数据库 >

[MySQL]-->查询5天之内过生日的同事中的跨年问题的解决过程

时间:2022-03-13 23:12

前言:
        遇到朋友提问,如下:
SELECT * FROM ali_users WHERE  DATEDIFF(CAST(CONCAT(DATE_FORMAT(NOW(),‘%y‘),DATE_FORMAT(birthday,‘-%m-%d‘))AS DATE),CAST(DATE_FORMAT(NOW(),‘%y-%m-%d‘) AS DATE)) <=1
上面的可以找到今天或者明天过生日的
假设今天是12月31日,这时候来年的1月1日的就找不到了,怎么办?

1,准备测试数据,需要包含跨年的数据

1.1,准备测试数据的SQL

  1. 1.2,在数据库命令行执行SQL

    1. 2,写出查询SQL
      SELECT * FROM ali_users WHERE 
      /*不跨年的查询*/
      DATEDIFF(CAST(CONCAT(YEAR(NOW()),DATE_FORMAT(birthday,‘-%m-%d‘))AS DATE),CAST(DATE_FORMAT(NOW(),‘%y-%m-%d‘) AS DATE)) BETWEEN 0 AND 4
      OR/* or后面的是捎带解决跨年问题*/ 
      DATEDIFF(CAST(CONCAT(YEAR(NOW())+1,DATE_FORMAT(birthday,‘-%m-%d‘))AS DATE),CAST(DATE_FORMAT(NOW(),‘%y-%m-%d‘) AS DATE)) BETWEEN 0 AND 4;

      2,1,跨年问题分析
      因为跨年的时候生日字段通常月份比较小是1月,所以如果利用DATEDIFF来判断要与月份比较大12月来比较得到相差天数在N天之内的话,就需要YEAR(NOW())+1,当年年份+1再加上月份才能与NOW()比较得出真实的相差天数。

      打个比方,今天是2013年12月30日,要查询出来5天之内的过生日的同事,那么2014年1月1日2日3日的也在查询范围之内,这个时候就需要CONCAT(YEAR(NOW())+1,DATE_FORMAT(birthday,‘-%m-%d‘)年份加1形成2014-01-01才能与今天的2013-12-30进行比较得出正确的相差天数。

      2.2,5天之内的设定
              N天之内,用 BETWEEN 0 AND N 来判断,如果是5天之内(包含今天)那么N值就是4,就是 BETWEEN 0 AND 4

      3,验证数据
      比如提醒最近5天之内(包括今日)过生日的同事,生日快乐。

      3.1,查询的数据都在今年之内的,比如今天是8月30日,那么需要执行的SQL如下:
      SELECT * FROM ali_users WHERE 
      DATEDIFF(CAST(CONCAT(YEAR(NOW()),DATE_FORMAT(birthday,‘-%m-%d‘))AS DATE),CAST(DATE_FORMAT(NOW(),‘%y-%m-%d‘) AS DATE)) BETWEEN 0 AND 4
      OR/* or后面的是捎带解决跨年问题*/ 
      DATEDIFF(CAST(CONCAT(YEAR(NOW())+1,DATE_FORMAT(birthday,‘-%m-%d‘))AS DATE),CAST(DATE_FORMAT(NOW(),‘%y-%m-%d‘) AS DATE)) BETWEEN 0 AND 4;

      查询的结果应该是从今天8月30日到9月3日之间过生日的同事,包括LiuEr,SongQi,HuangBa,ZengJiu,LuoShi;
      执行如下所示,符合预期,如下所示:


      1. 3.2,查询的生日有跨年的
                比如今天是2013年12月30日,要查询5天之内过生日的同事,那么就有2013年的12月30日31日过生日的,也有2014年1月1日2日3日过生日的同事,因为今天是8月30日,所以要把Step#2中的SQL的NOW()改成‘2013-12-30 00:10:10‘来进行测试,SQL整理如下:
        SELECT * FROM ali_users WHERE 
        DATEDIFF(CAST(CONCAT(YEAR(‘2013-12-30 00:10:10‘),DATE_FORMAT(birthday,‘-%m-%d‘))AS DATE),CAST(DATE_FORMAT(‘2013-12-30 00:10:10‘,‘%y-%m-%d‘) AS DATE)) BETWEEN 0 AND 4
        OR/* or后面的是捎带解决跨年问题*/ 
        DATEDIFF(CAST(CONCAT(YEAR(‘2013-12-30 00:10:10‘)+1,DATE_FORMAT(birthday,‘-%m-%d‘))AS DATE),CAST(DATE_FORMAT(‘2013-12-30 00:10:10‘,‘%y-%m-%d‘) AS DATE)) BETWEEN 0 AND 4;

        查询的结果应该是从今天8月30日到9月3日之间过生日的同事,包括Licy,Cari,ZhangSan,LiSi,Mark。
        执行结果如下所示,符合预期,如下所示:

        1. 4,总结
              这种类似的场景,涉及到查询多少天之内的数据,以及涉及到跨度范围比较大的查询(比如跨年或者跨部门,跨省、跨国、跨公司等等),都可以用这个思路来需求解决问题的方法。
              
              

热门排行

今日推荐

热门手游