2012-07-30 35 views
4

這是一個食品服務系統... 我有一個名爲detalle_regimen_paciente的表,它存儲飲食,早餐爲星期一 - 星期日(週一爲1,星期日爲7,智利爲7)類型) 也具有特定的服務時間。mysql選擇當前時間旁邊的記錄

+---+---------+-----------+--------------+---+ 
|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 | 
+---+---------+-----------+--------------+---+ 

所以我與查詢掙扎了兩天左右(更孤單的分貝比這...一些多對多關係這是我從哪裏可以得到一個總消耗消耗表員工),我發現問題是,我無法找到一種方法來選擇在08:00(星期一是記錄ID#1),使用當前日期和當前時間只是吃飯...

so in一個星期一在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) 

也許我只是問錯或missusing時間函數。

請在這裏幫忙。

thx提前。

+0

你能定義hora_carga是什麼嗎? – golja 2012-07-30 22:55:21

回答

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 
; 
+0

爲'dia'添加某種模7比較,這將是一個很好的答案... – MvG 2012-07-30 23:14:12

+0

@MvG:是的,這個查詢將從週日晚餐休息到週日午夜。 – 2012-07-30 23:15:23

+0

@MvG:完成。沒有modulos :) – 2012-07-30 23:30:07

2

如果您的查詢限制resultst既

  • 當前日期和
  • 時間仍然趴在未來

那麼你可以得到最近的這些使用

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來指代下一個這一天可能看起來有點令人困惑,所以它當然值得評論。

作爲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等等。對於當天的用餐,我們只在當前時間之後進行。對於所有其他日子,任何時間都可以。