0

我有一个具有以下结构的 MySQL 表:

    id |    date    |  type   |     description
    ---------------------------------------------------
     0 | 1979-09-20 | 'bday'  | 'Birthday Employee1 '
     1 | 1984-05-04 | 'bday'  | 'Birthday Employee2 '
     2 | 1989-01-04 | 'bday'  | 'Birthday Employee3 '
     3 | 2013-10-10 | 'visit' | 'Visit of Visitor1  '

此表应处理员工门户中所有即将发生和过去的事件。有两种不同类型的事件;生日和访问。这些在列类型中被声明为字符串。生日应该只输入一次,而不是每年,所以需要一个复杂的查询来处理这种情况:

   SELECT * ,
   CASE type
   WHEN 'bday'
   THEN
     (CASE 
      WHEN ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )< NOW()
       THEN ADDDATE(ADDDATE(datum,INTERVAL YEAR(NOW())- YEAR(date) YEAR),
       INTERVAL 1 YEAR)
       ELSE ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )
     END)
   ELSE date
   END 
   AS dates
   FROM events
   WHERE date > NOW() AND type='visit' OR ADDDATE(date, INTERVAL 
   YEAR NOW())-YEAR( date ) YEAR) > NOW() AND type='bday'
   ORDER BY dates ASC
   LIMIT 0 ,10

这个查询对我不起作用,因为我在括号中添加了嵌套的 case 子句。我将其替换为以下行

   ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )

这行得通,但问题是 - 正如您在嵌套的 CASE 子句中看到的那样 - 不会选择最近一年已经发生的生日。因此,额外 CASE 的目的是确定年份应该是 2013 年还是 2014 年(如果它已经发生在 2013 年)。

这对于一年中前两周的生日非常重要。提醒通知必须在前一年已经看到,否则没有多大意义。

所以实际上我只需要弄清楚为什么嵌套的 CASE 子句不起作用。也有可能显然有更简单的方法来解决这个问题,但现在我看不到它们。

4

2 回答 2

1

我想你想显示“近”未来的事件和生日。一种方法是将逻辑分成 3 个部分和UNION它们。这三个部分将是:

  • 访问
  • 今年的生日
  • 明年的生日

    ( SELECT id, date, type, description, 
             date AS dates
      FROM events
      WHERE type='visit' 
        AND date > NOW() 
    )
    UNION ALL
    ( SELECT id, date, type, description,
             ADDDATE(date, INTERVAL (YEAR(NOW())-YEAR(date)) YEAR)
      FROM events
      WHERE type='bday'
        AND ADDDATE(date, INTERVAL (YEAR(NOW())-YEAR(date)) YEAR) > NOW()
    )
    UNION ALL
    ( SELECT id, date, type, description,
             ADDDATE(date, INTERVAL (1+YEAR(NOW())-YEAR(date)) YEAR)
      FROM events
      WHERE type='bday'
    )
    ORDER BY dates ASC
    LIMIT 0, 10 ;
    

你的CASE似乎也是正确的。但是如果你想考虑所有的生日,你应该用OR ADDDATE(date, INTERVAL YEAR NOW())-YEAR( date ) YEAR) > NOW() AND type='bday'简单的替换条件OR type='bday'

于 2013-09-09T08:22:26.823 回答
0

您必须更改 YEAR DIFF 部分:

SELECT ADDDATE(date, INTERVAL (FLOOR(DATEDIFF(CURDATE(),date)/365)) YEAR )<NOW()

id=0 的示例

SELECT ADDDATE('1979-09-20', 
INTERVAL (FLOOR(DATEDIFF(CURDATE(),'1979-09-20')/365)) YEAR )< NOW();
于 2013-09-09T08:15:38.513 回答