4

这是一个食品服务系统......我有一个名为 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 的餐点(即记录 id #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)

也许我只是在问错或误用时间功能。

请在这里帮忙。

提前谢谢。

4

2 回答 2

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 星期天。您可以在没有任何魔法的情况下使用 MySQLDAYOFWEEK来引用第二天的事实可能看起来有点令人困惑,所以它当然值得评论。

作为替代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,依此类推。对于当天的餐点,我们只吃当前时间之后的餐点。对于其他所有日子,任何时间都可以。

于 2012-07-30T23:30:41.990 回答
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
; 
于 2012-07-30T23:01:07.210 回答