복붙노트

[SQL] 최저 근무 시간 저장하는 방법과 쿼리를 효율적으로

SQL

최저 근무 시간 저장하는 방법과 쿼리를 효율적으로

나는 상점에 대한 작업 시간을 저장하기 위해 계획입니다. 나는 근무 시간 필드에 가장 적합한 모델링가 무엇인지 궁금하네요 그래서 매우 효율적인 방법으로 현재의 순간에 개방 / 폐쇄 상점의 목록을 얻을 수 있습니다.

해결법

  1. ==============================

    1.정상 작동 시간을 저장하려면 포함 된 레코드 번호를 저장해야합니다 :

    정상 작동 시간을 저장하려면 포함 된 레코드 번호를 저장해야합니다 :

    나는 각 상점 공휴일 동안 시간을 ​​감소, 또는 일부 재정의 레코드를 저장해야하므로, 공장 가동 중단을가했다고 예를 들어 가정 :

    열려있는 상점을 찾으려면 사소한,하지만 당신은 또한 재정의 시간이 있는지 확인해야합니다 :

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

    반환 된 기록이있는 경우, 그 상점은 다른 시간이 있거나 닫혀있다.

    이 여기에 할 수있는 좋은 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은 하나의 호출을해야한다는 점에서 효율적이다. 당신은 테스트해야하고 사양이 수행 여부를 확인할 수 있습니다. 그렇지 않다면, 당신은 몇 가지 지표로 재생할 수 있습니다.

    편집하다

    테스트. 아니 완벽한 테스트,하지만 일부.

    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)
    
  2. ==============================

    2.하자 모든 영업 시간은 매주 동일 고려한다. 다음 표에 대한 어떤 일이 그래서 :

    하자 모든 영업 시간은 매주 동일 고려한다. 다음 표에 대한 어떤 일이 그래서 :

    , 즉를 shop_id에 의해 확인 된 점포 테이블을 확인하고 영업 시간을 삽입 :

    다음 선택 :

    SELECT shop_id
    FROM opening_hours
    WHERE WEEKDAY(NOW()) = week_day
    AND TIME(NOW()) BETWEEN opens_at AND closes_at
    
  3. from https://stackoverflow.com/questions/4464898/best-way-to-store-working-hours-and-query-it-efficiently by cc-by-sa and MIT license