SQL that list all birthdays within the next and previous 14 days

前端 未结 7 1488
梦谈多话
梦谈多话 2021-01-05 22:30

I have a MySQL member table, with a DOB field which stores all members\' dates of birth in DATE format (Notice: it has the \"Year\" pa

相关标签:
7条回答
  • 2021-01-05 22:50

    Here's the simplest code to get the upcoming birthdays for the next x days and previous x days

    this query is also not affected by leap-years

    SELECT name, date_of_birty 
    FROM users 
    WHERE DATE(CONCAT(YEAR(CURDATE()), RIGHT(date_of_birty, 6)))
              BETWEEN 
                  DATE_SUB(CURDATE(), INTERVAL 14 DAY)
              AND
                  DATE_ADD(CURDATE(), INTERVAL 14 DAY)
    
    0 讨论(0)
  • 2021-01-05 22:55

    There are a number of options, I would first try to transform by number of years between current year and row's year (i.e. Add their age).

    Another option is day number within the year (but then you have still to worry about the rollover arithmetic or modulo).

    0 讨论(0)
  • 2021-01-05 23:01

    My first thought was it would be easy to just to use DAYOFYEAR and take the difference, but that actually gets kinda trick near the start/end of a yeay. However:

    WHERE 
    DAYOFYEAR(NOW()) - DAYOFYEAR(dob) BETWEEN 0 AND 14 
    OR DAYOFYEAR(dob) - DAYOFYEAR(NOW())  > 351
    

    Should work, depending on how much you care about leap years. A "better" answer would probably be to extract the DAY() and MONTH() from the dob and use MAKEDATE() to build a date in the current (or potential past/following) year and compare to that.

    0 讨论(0)
  • 2021-01-05 23:08

    This is my query for the 30 days before check:

    select id from users where 
    ((TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d')))-TO_DAYS(NOW()))>=-30 
    AND (TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d')))-TO_DAYS(NOW()))<=0)
    OR (TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d')))-TO_DAYS(NOW()))>=(365-31)
    

    and 30 days after:

    select id from users where 
    ((TO_DAYS(NOW())-TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d'))))>=-31 
    AND (TO_DAYS(NOW())-TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d'))))<=0)
    OR (TO_DAYS(NOW())-TO_DAYS(concat(DATE_FORMAT(NOW(),'%Y'), '-', DATE_FORMAT(date_of_birth, '%m-%d'))))>=(365-30)
    
    0 讨论(0)
  • 2021-01-05 23:10

    My solution is as follow:

    select cm.id from users cm where 
    date(concat(
    year(curdate()) - (year(subdate(curdate(), 14)) < year(curdate())
    and month(curdate()) < month(cm.birthday)) + (year(affffdate(curdate(), 14)) > year(curdate())
    and month(curdate()) > month(cm.birthday)), date_format(cm.birthday, '-%m-%d'))) between subdate(curdate(), 14)
    and affffdate(curdate(), 14);
    

    It looks like it works fine when the period captures the current and next year or the current and previous year

    0 讨论(0)
  • 2021-01-05 23:14

    @Eli had a good response, but hardcoding 351 makes it a little confusing and gets off by 1 during leap years.

    This checks if birthday (dob) is within next 14 days. First check is if in same year. Second check is if its say Dec 27, you'll want to include Jan dates too.

    With DAYOFYEAR( CONCAT(YEAR(NOW()),'-12-31') ), we are deciding whether to use 365 or 366 based on the current year (for leap year).

    SELECT dob
    FROM birthdays
    WHERE DAYOFYEAR(dob) - DAYOFYEAR(NOW()) BETWEEN 0 AND 14 
    OR 
    DAYOFYEAR( CONCAT(YEAR(NOW()),'-12-31') ) - ( DAYOFYEAR(NOW()) - DAYOFYEAR(dob) ) BETWEEN 0 AND 14 
    
    0 讨论(0)
提交回复
热议问题