mysql选择当前时间旁边的记录

时间:2012-07-30 22:49:58

标签: mysql time dayofweek

这是一个食品服务系统......  我有一个名为detalle_regimen_paciente的餐桌,它储存饮食,星期一供应早餐 - 星期日(星期一为1,星期日为7,智利型) 也有特定的服务时间。

+---+---------+-----------+--------------+---+
|id | name    |hora_carga |hora_servicio |day|
+---+---------+-----------+--------------+---+
|1  |breakfast|08:00      |09:00         |1  |
+---+---------+-----------+--------------+---+
|2  |lunch    |10:00      |13:00         |1  |
+---+---------+-----------+--------------+---+
|3  |breakfast|08:00      |09:00         |2  |
+---+---------+-----------+--------------+---+
|2  |lunch    |10:00      |13:00         |2  |
+---+---------+-----------+--------------+---+

所以我在查询中挣扎了大约两天(数据库中的数据比这更多......有些n:m关系是这个消费表,我可以从中获得一个员工的总消费量)我发现问题是我找不到一种方法来选择使用当前日期和当前时间在08:00星期一用餐(这是记录号#1)......

所以在07:58的星期一这应该只返回id为1的记录,因为它是下一顿饭,也是为雇员收取的下一顿饭。

+---+---------+-------------+---+
|1  |breakfast|08:00        |1  |
+---+---------+-------------+---+

这里是sql到目前为止,但它似乎只是过滤了一天......

select detalle_regimen_paciente.hora_carga
from
detalle_regimen_paciente
where
detalle_regimen_paciente.hora_servicio > CURTIME() AND
detalle_regimen_paciente.hora_carga > CURTIME()
AND
detalle_regimen_paciente.dia = (select DAYOFWEEK(CURDATE())-1)

也许我只是错误地或错过了时间函数。

请帮忙。

提前thx。

2 个答案:

答案 0 :(得分:2)

SELECT 
    *                          --- select the columns you need (hora_carga ?)
FROM
  ( SELECT *  
    FROM detalle_regimen_paciente   
    WHERE  hora_servicio > CURTIME()     
         AND
           dia = DAYOFWEEK(CURDATE())-1
       OR 
         dia > DAYOFWEEK(CURDATE())-1
    ORDER BY dia, hora_servicio
      LIMIT 1
  ) AS a
UNION ALL
SELECT *
FROM
  ( SELECT *     
    FROM detalle_regimen_paciente   
    ORDER BY dia, hora_servicio
      LIMIT 1
  ) AS b
ORDER BY dia DESC, hora_servicio DESC
  LIMIT 1
; 

答案 1 :(得分:2)

如果您的查询将结果限制为

  • 当天和
  • 时代仍然存在于未来

然后你可以使用

获得最近的这些
SELECT … FROM … WHERE …
ORDER BY hora_servicio ASC
LIMIT 1

这只是按小时对结果行进行排序,并选择第一行。在当天的最后一餐之后,您将不得不等到午夜,然后此查询将返回非空结果。你最好用工会来解决这个问题:

(SELECT 0 AS tomorrow, … FROM …
 WHERE dia = ((DAYOFWEEK(CURDATE()) + 5) MOD 7) + 1
   AND hora_servicio > CURTIME()
)
UNION ALL
(SELECT 1 AS tomorrow, … FROM …
 WHERE dia = DAYOFWEEK(CURDATE()) -- this really is the next day
)
ORDER BY tomorrow, hora_servicio
LIMIT 1

您的代码也可能需要这个工作日计算。以下是它的工作原理:

                                        Su Mo Tu We Th Fr Sa
  DAYOFWEEK(CURDATE())                   1  2  3  4  5  6  7
 (DAYOFWEEK(CURDATE()) + 5)              6  7  8  9 10 11 12
((DAYOFWEEK(CURDATE()) + 5) MOD 7)       6  0  1  2  3  4  5
((DAYOFWEEK(CURDATE()) + 5) MOD 7) + 1   7  1  2  3  4  5  6

您的版本将在星期日计算0而不是7。事实上你可以使用MySQL DAYOFWEEK而没有任何魔法来引用 next 那天可能看起来有点令人困惑,所以它肯定值得评论。

作为dia = ((DAYOFWEEK(CURDATE()) + 5) MOD 7) + 1的替代方案,您可以编写dia MOD 7 = DAYOFWEEK(CURDATE()) - 1,因为这将为双方使用从零开始的数字。但是,结果可能效率较低,因为数据库必须计算左侧的值,这会破坏索引和类似的优化。所以我宁愿把所有的计算都放到右边。

感谢@ypercube让我第二天想到了。

如果您想考虑未来一天以上(我希望您不必为太多人这样做),那么您可以这样做:

SELECT dia, hora_servicio
FROM detalle_regimen_paciente
WHERE dia <> ((DAYOFWEEK(CURDATE()) + 5) MOD 7) + 1
   OR hora_servicio > CURTIME()
ORDER BY (dia - DAYOFWEEK(CURDATE()) + 1) MOD 7 ASC,
         hora_servicio ASC
LIMIT 1

这里的想法是第一个ORDER BY术语计算未来的天数:当前日期的值为0,明天为1,后一天为2,依此类推。对于当天的用餐,我们只接受当前时间之后的用餐。所有其他日子,任何时间都可以。