MySQL查询和间隔

时间:2011-02-28 08:36:22

标签: php sql date intervals

这是我做过的最棘手的问题: http://robertr.pastebin.com/X4bG4pFp

"SELECT  `user`.`id` ,  `user`.`fname` ,  `user`.`lname` , 
YEAR(  `user`.`bday` ) AS  `bday_year` ,  `user`.`class_id` , 
( SELECT  `class`.`class_name` 
  FROM  `wp_class_classes`  `class` 
  WHERE  `user`.`class_id` =  `class`.`id`) AS  `class_name` 
FROM  `wp_class_users`  `user` 
WHERE MONTH(  `bday` ) = $month AND DAY(  `bday` ) = $day 
OR  `user`.`fname` = 
( SELECT  `name`.`names` 
  FROM  `wp_class_namedays`  `name` 
  WHERE  `name`.`day` =  '$month.$day'
  AND  `user`.`fname` =  `name`.`names` )

此查询从三个不同的数据库表中获取数据,以检查数据库中是否有人,今天谁参加了聚会。在拉脱维亚,我们也有名字日。无论如何,这个查询效果很好,并且做得很好,但是现在我想让它变得更酷。

我希望它能够表明,谁将在下周举行派对。您可能已经注意到Facebook每周末都会向您发送这些电子邮件,以显示谁将迎来生日。

但我无法理解如何获得至少那个间隔?

我记得PHP有一些很好的功能,您可以在哪一天开始查找,等等,但也许这里有一些明亮的心,并愿意帮助我更快地向前推进。

2 个答案:

答案 0 :(得分:2)

SELECT
  `user`.`id`,
  `user`.`fname`,
  `user`.`lname` ,
  YEAR(`user`.`bday`) AS  `bday_year`,
  `user`.`class_id`,
  (
    SELECT
      `class`.`class_name`
    FROM  `wp_class_classes`  `class`
    WHERE  `user`.`class_id` =  `class`.`id`
  ) AS  `class_name`,
  CASE
    WHEN MONTH(`week`.`Date`) = MONTH(`user`.`bday`) AND
         DAY(`week`.`Date`) = DAY(`user`.`bday`) THEN 1
    ELSE 2
  END AS `event_type`
FROM  `wp_class_users`  `user`
  LEFT JOIN  `wp_class_namedays`  `name` ON  `user`.`fname` =  `name`.`names`
  LEFT JOIN  (
    SELECT CURDATE() + INTERVAL (1 - DAYOFWEEK(CURDATE())) DAY AS `Date`  UNION ALL
    SELECT CURDATE() + INTERVAL (2 - DAYOFWEEK(CURDATE())) DAY  UNION ALL
    SELECT CURDATE() + INTERVAL (3 - DAYOFWEEK(CURDATE())) DAY  UNION ALL
    SELECT CURDATE() + INTERVAL (4 - DAYOFWEEK(CURDATE())) DAY  UNION ALL
    SELECT CURDATE() + INTERVAL (5 - DAYOFWEEK(CURDATE())) DAY  UNION ALL
    SELECT CURDATE() + INTERVAL (6 - DAYOFWEEK(CURDATE())) DAY  UNION ALL
    SELECT CURDATE() + INTERVAL (7 - DAYOFWEEK(CURDATE())) DAY
  ) `week`
    ON CONCAT(MONTH(`week`.`Date`), '.', DAY(`week`.`Date`)) IN (
      CONCAT(MONTH(`user`.`bday`), '.', DAY(`user`.`bday`)),
      `name`.`day`
    )
WHERE `week`.`Date` IS NOT NULL

用户表与名称日表连接,然后将结果集与当前周的日期进行比较。最终结果集仅列出那些在一周内发生生日或姓名天数的用户。

如果您想了解下周的事件,您只需将week.Date定义中的时间间隔更改为8 - DAYOFWEEK...9 - DAYOFWEEK...等。

最后一点是,您可以使用INNER JOIN代替选择列表中的相关子查询,如下所示:

SELECT
  `user`.`id`,
  `user`.`fname`,
  `user`.`lname` ,
  YEAR(`user`.`bday`) AS  `bday_year`,
  `user`.`class_id`,
  `class`.`class_name`
FROM  `wp_class_users`  `user`
  INNER JOIN  `wp_class_classes`  `class` ON  `user`.`class_id` =  `class`.`id`
  LEFT JOIN  `wp_class_namedays`  `name` ON  ...  /* the rest of the above script */

上面定义的event_type列可以告诉您事件是否是生日,但它不会让您知道该特定人员的生日和名称日是否都是。

如果您希望有这种区别,可以像这样更改event_type定义:

CASE
  WHEN MONTH(`week`.`Date`) = MONTH(`user`.`bday`) AND
       DAY(`week`.`Date`) = DAY(`user`.`bday`) THEN 1
  ELSE 0
END +
CASE CONCAT(MONTH(`week`.`Date`), '.', DAY(`week`.`Date`))
  WHEN `name`.`day` THEN 2
  ELSE 0
END AS `event_type`

现在该列的结果将是:

  • 1 - 生日
  • 2 - 名称日
  • 3 - 两个

此外,您可以使用'B'代替1'N'代替2(以及''代替0)。结果将是'B''N''BN'。但是,不确定+是否可以用于连接。如果没有,请将CASE放入CONCAT()

答案 1 :(得分:0)

我不确定我的查询是否正确,但the MySQL docs中提到了SYSDATE()命令。你可能想尝试类似的东西:

... where date = SYSDATE() + 7

(检查语法,我来自Oracle;))

这将在未来7天内让各方接受。