sql >> データベース >  >> RDS >> Mysql

労働時間を保存し、効率的に照会するための最良の方法

    通常の営業時間を保存するには、以下を含む多数のレコードを保存する必要があります。

    • ショップ-INTEGER
    • DayOfWeek-INTEGER(0-6)
    • OpenTime-時間
    • CloseTime-時間

    たとえば、各ショップの祝日は営業時間が短縮されたり、工場が閉鎖されたりしたため、オーバーライドレコードも保存する必要があると思います。

    • ショップ-INTEGER
    • OverrideStartDate-日付
    • OverrideEndDate-日付
    • DayOfWeek-INTEGER(0-6)
    • AltOpenTime-時間
    • AltCloseTime-時間
    • クローズ-INTEGER(0、1)

    オープンショップを見つけるのは簡単ですが、オーバーライド時間があるかどうかも確認する必要があります:

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

    返品されたレコードがある場合、それらのショップは1時間おきに営業しているか、休業しています。

    ここで実行できる優れたSQL-fuがあるかもしれませんが、これで基本がわかります。

    編集

    私はこれをテストしていませんが、これであなたを近づけるはずです:

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

    編集

    効率に関しては、MySQLを1回呼び出すだけでよいという意味で効率的です。これは、ネットワークを介している場合にボトルネックになることがよくあります。これが仕様どおりに機能するかどうかをテストして確認する必要があります。そうでない場合は、いくつかのインデックスで遊ぶことになるかもしれません。

    編集

    テスト。完全なテストではありませんが、いくつかあります。

    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)
    


    1. MySQLテーブルに配列を格納するためのBLOBとVARCHAR

    2. 2つの別々のデータベースからの結果の結合

    3. 忙しいデータの人々のための7つの無料のデータベース作図ツール

    4. mysqlエラー1025(HY000):'./foo'(errorno:150)の名前変更時のエラーはどういう意味ですか?