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

だから私は約2日間クエリに苦労しています(データベースにはこれよりも多くあります...いくつかのn:m関係は、これが1人の従業員の合計消費量を取得できる消費テーブルです)。問題は、現在の日付と現在の時刻を使用して、月曜日の 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)

たぶん、時間関数の使い方が間違っているか、間違っているだけです。

ここで助けてください。

事前にt​​hx。

4

2 に答える 2

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 に答える
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

あなたのバージョンは、日曜日の 7 ではなく 0 を計算します。DAYOFWEEK魔法をかけずに MySQL を使用して翌日を参照できるという事実は、少し混乱するように思えるかもしれないので、コメントする価値があることは確かです。

代わりに、dia = ((DAYOFWEEK(CURDATE()) + 5) MOD 7) + 1と書くこともできますdia MOD 7 = DAYOFWEEK(CURDATE()) - 1。これは、両側にゼロベースの数値を使用するためです。ただし、データベースは左側の値を計算する必要があるため、結果の効率が低下する可能性があります。これにより、インデックス作成や同様の最適化が機能しなくなります。したがって、すべての計算を右側に配置したいと思います。

翌日のことを考えさせてくれた@ypercubeに感謝します。

1 日以上先のことを考えたい場合 (あまりにも多くの人のためにそうする必要がないことを願っています)、次のようにすることができます。

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 に答える