2010-12-16 10 views

答えて

44

を通常の動作時間を保存するには、あなたが含むレコードの数を格納する必要があります:

  • ショップ - INTEGER
  • のDayOfWeek - INTEGER( 0-6)
  • OpenTime - TIME
  • CloseTim - INTEGER
    • ショップ: - 電子TIME

    は、私はあなたにもいくつかのオーバーライドレコードを格納する必要がありますので、各店舗は、祝日の間、時間を減少、または植物の停止を持っていること、たとえば仮定します

  • OverrideStartDate - DATE
  • OverrideEndDate - DATE
  • のDayOfWeek - INTEGER(0-6)
  • AltOpenTime - TIME
  • AltCloseTime - TIME
  • クローズ - INTEGER(0、1)

オープンのお店を検索するには簡単ですが、あなたはまた、オーバーライド時間があるかどうかを確認する必要があります。

SELECT Shop 
FROM OverrideHours 
WHERE OverrideStartDate <= NOW() 
AND OverrideEndDate >= NOW() 
AND DayOfWeek = WEEKDAY(NOW()) 

があった場合いずれかのレコードが返された場合、それらの店舗は交替時間を有するか、または閉鎖される。

あなたがここで行うことができる素晴らしいSQL-fuがあるかもしれませんが、これはあなたに基本を与えます。

EDIT

私はこれをテストしていませんが、これは近くにあなたを取得する必要があります。

効率については
SELECT Normal.Shop 
FROM Normal 
LEFT JOIN Override 
ON Normal.Shop = Override.Shop 
AND Normal.DayOfWeek = Override.DayOfWeek 
AND NOW() BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate 
WHERE Normal.DayOfWeek = WEEKDAY(NOW()) 
AND ((Override.Shop IS NULL AND TIME(NOW()) BETWEEN Normal.OpenTime AND Normal.CloseTime) 
OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(NOW()) BETWEEN Override.AltOpenTime AND Override.AltCloseTime)) 

EDIT

、それは意味で効率的であることMySQLを1回呼び出すだけで済みます。これは、ネットワークを介している場合はしばしばボトルネックになります。これがあなたの仕様に準拠しているかどうかをテストして調べる必要があります。もしそうでなければ、いくつかの指数で遊ぶかもしれません。

EDIT

テスト。テストを完了するのではなく、いくつか。

mysql> select * from Normal; 
+------+-----------+----------+-----------+ 
| Shop | DayOfWeek | OpenTime | CloseTime | 
+------+-----------+----------+-----------+ 
| 1 |   1 | 09:00:00 | 17:00:00 | 
| 1 |   5 | 09:00:00 | 16:00:00 | 
| 2 |   1 | 09:00:00 | 17:00:00 | 
| 2 |   5 | 09:00:00 | 17:00:00 | 
+------+-----------+----------+-----------+ 
4 rows in set (0.01 sec) 

mysql> select * from Override; 
+------+-------------------+-----------------+-----------+-------------+--------------+--------+ 
| Shop | OverrideStartDate | OverrideEndDate | DayOfWeek | AltOpenTime | AltCloseTime | Closed | 
+------+-------------------+-----------------+-----------+-------------+--------------+--------+ 
| 2 | 2010-12-01  | 2010-12-31  |   1 | 09:00:00 | 18:00:00  |  0 | 
| 2 | 2010-12-01  | 2010-12-31  |   5 | 09:00:00 | 18:00:00  |  0 | 
| 1 | 2010-12-01  | 2010-12-31  |   1 | 09:00:00 | 17:00:00  |  1 | 
+------+-------------------+-----------------+-----------+-------------+--------------+--------+ 
3 rows in set (0.00 sec) 

mysql> SET @whenever = TIMESTAMP('2010-11-23 16:05'); 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT WEEKDAY(@whenever); 
+--------------------+ 
| WEEKDAY(@whenever) | 
+--------------------+ 
|     1 | 
+--------------------+ 
1 row in set (0.00 sec) 

mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime) OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime)); 
+------+ 
| Shop | 
+------+ 
| 1 | 
| 2 | 
+------+ 
2 rows in set (0.00 sec) 

mysql> SET @whenever = TIMESTAMP('2010-11-23 17:05'); 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime) OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime)); 
Empty set (0.01 sec) 

mysql> SET @whenever = TIMESTAMP('2010-12-25 16:05'); 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime) OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime)); 
+------+ 
| Shop | 
+------+ 
| 2 | 
+------+ 
1 row in set (0.00 sec) 

mysql> SET @whenever = TIMESTAMP('2010-11-23 17:05'); 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT WEEKDAY(@whenever); 
+--------------------+ 
| WEEKDAY(@whenever) | 
+--------------------+ 
|     1 | 
+--------------------+ 
1 row in set (0.00 sec) 

mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime) OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime)); 
Empty set (0.00 sec) 
+0

簡単な質問: 'Shop'、' DayOfWeek'、 'OpenTime'、' CloseTime'にインデックスを置くことをお勧めしますか? – RabidFire

+1

@RabidFireについては、http://stackoverflow.com/questions/3049283/mysql-indexes-what-are-the-best-practisesへの回答をご覧ください。探している主な効率が(挿入とは対照的に)クエリである場合、WHEREまたはJOIN ONで使用されるフィールドにインデックスを追加すると、検索が高速化されます。どの人が最も効果的かを調べるためには、テストする必要があります。 –

+0

@RobertGowland夜のブルッスンが午後5時にオープンし、翌日午前3時にクローゼットをするとどうなりますか? – Antoniossss

8

すべての営業時間は毎週同じです。それでは、次の表について:

  • shop_id - INTEGER(またはお店のいずれかの一意の識別子)
  • WEEK_DAY - INTEGER(0 =月曜日 - 6 =日曜日)
  • opens_at - TIME(あなたの地域のタイムゾーンを使用します)
  • closes_at - その後、TIME(あなたの地域のタイムゾーンを使用)

shop_idで識別される店舗用のテーブルを作成し、営業時間、すなわち挿入します

  • 1,0 8:00、午後05時00分
  • ...
  • 1、5、8:00 12:00
  • 2、0、7時30分、12時30
  • 2、0、13時30分、午後05時30
  • 2、1、7:30、12時30
  • 2、1、13時30分、午後05時30
  • ...

[選択:

SELECT shop_id 
FROM opening_hours 
WHERE WEEKDAY(NOW()) = week_day 
AND TIME(NOW()) BETWEEN opens_at AND closes_at 
関連する問題