【问题标题】:SQL that list all birthdays within the next and previous 14 days列出未来 14 天内和过去 14 天内所有生日的 SQL
【发布时间】:2010-11-01 12:29:04
【问题描述】:

我有一个 MySQL member 表,其中有一个 DOB 字段,它以 DATE 格式存储所有成员的出生日期(注意:它有“年份”部分)

我正在尝试找到正确的 SQL 来:

  • 列出未来 14 天内的所有生日

另一个查询:

  • 列出过去 14 天内的所有生日

直接比较当前日期:

(DATEDIFF(DOB, now()) <= 14 and DATEDIFF(DOB, now()) >= 0)

由于当前年份和 DOB 年份不同,因此不会获取任何内容。

但是,将 DOB 转换为“今年”根本行不通,因为今天可能是 1 月 1 日,候选人的 DOB 可能是 12 月 31 日(反之亦然)

如果您能提供帮助,那就太好了,非常感谢! :)

【问题讨论】:

  • 哇。我以为这很容易。我做了一些修改,这比我乍一看要难得多。感谢 Code Kata!

标签: sql mysql date


【解决方案1】:

有很多选择,我会首先尝试按当前年份和行年份之间的年数进行转换(即添加他们的年龄)。

另一个选项是一年中的天数(但您仍然需要担心翻转算术或模数)。

【讨论】:

    【解决方案2】:

    简单,

    我们可以通过这段代码获得更接近的生日(即今年的生日):

    dateadd(year,datediff(year,dob,getdate()),DOB)
    

    在您的比较中使用它!它会起作用的。

    【讨论】:

    • 我仍然不确定...介意将其转换为 mysql 版本吗?非常感谢!
    • 你是对的,对不起,只是不假思索地打字,只是习惯了SQL Server。 DATE_ADD 等于 SQL Server 的 DATEADD。在 mySQL 中是否有等效于 DATEDIFF 的东西,即可以让我知道两个日期之间的距离?
    【解决方案3】:

    我的第一个想法是只使用 DAYOFYEAR 并获得差异会很容易,但这实际上在接近一年的开始/结束时有点诡计。然而:

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

    应该有效,具体取决于您对闰年的关心程度。 “更好”的答案可能是从 dob 中提取 DAY() 和 MONTH() 并使用 MAKEDATE() 在当前(或潜在的过去/以后)年份建立一个日期并与之进行比较。

    【讨论】:

      【解决方案4】:

      这是获取未来 x 天和前 x 天即将到来的生日的最简单代码

      此查询也不受闰年影响

      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)
      

      【讨论】:

      • 这对我来说似乎很简单,但如果当前日期类似于2014-12-30,则不会在2015-01-07 过生日...您必须复制该 WHERE 子句,将其添加为@ 987654324@ 大小写并修改如下:DATE(CONCAT(YEAR(CURDATE())+1, ... 将该年份添加到您比较的生成日期。
      【解决方案5】:

      @Eli 得到了很好的响应,但硬编码 351 使它有点混乱,并且在闰年会下降 1。

      这会检查生日 (dob) 是否在接下来的 14 天内。首先检查是否在同一年。第二个检查是如果它说 12 月 27 日,你也想包括 1 月的日期。

      对于DAYOFYEAR( CONCAT(YEAR(NOW()),'-12-31') ),我们正在根据当前年份(闰年)决定是使用 365 还是 366。

      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 
      

      【讨论】:

        【解决方案6】:

        这是我检查前 30 天的查询:

        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)
        

        30 天后:

        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)
        

        【讨论】:

          【解决方案7】:

          我的解决方法如下:

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

          当期间捕获当前和下一年或当前和上一年时,它看起来工作正常

          【讨论】:

            猜你喜欢
            • 2012-11-06
            • 2012-04-16
            • 2021-02-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-19
            • 2012-02-29
            相关资源
            最近更新 更多