Сохранение временных диапазонов в MySQL и определение, находится ли текущее время в пределах временного диапазона - PullRequest
3 голосов
/ 04 июня 2011

У меня есть таблица базы данных, в которой хранятся часы работы магазина в виде временного диапазона в формате TIME. Например, если часы работы магазина «9 утра-5 вечера», будет 2 столбца «hours_open» и «hours_close», где я храню 9:00 в «hours_open» и 17:00 в «hours_close». Чтобы определить, открыт ли магазин в данный момент или нет, я выполню запрос:

SELECT * 
  FROM shop 
 WHERE CAST(NOW() AS TIME) BETWEEN hours_open AND hours_close;

Что мне нужно сделать сейчас, так это разместить магазины с часами работы, которые открываются после полуночи, например, с 9:00 до 3:00. Кроме того, магазины могут иметь разные часы работы в разные дни, например: понедельник-четверг: 9 вечера - 3 часа ночи, пт-вс: 9 вечера - 5 утра.

Теперь я в тупике. Как мне поступить? У меня может быть пара 'hours_open' и 'hours_close' для каждого дня, например: 'mon_hours_open', 'mon_hours_close', 'tue_hours_open', 'tue_hours_close' ...

Но как мне обращаться с часами работы, которые идут после полуночи, например с 9 вечера до 5 утра?

Есть идеи? Я использую PHP с каркасом Codeigniter, если это поможет.

Ответы [ 4 ]

3 голосов
/ 04 июня 2011

Было бы проще проверить часы, если бы они хранились в отдельной таблице, что-то вроде

shop_working_hours (
  shop_id int FK,
  day_of_week int,
  hours_open time,
  hours close time,
  PK (shop_id, day_of_week)
)

Таким образом, запрос может быть таким:

SELECT s.*
FROM shop s
  INNER JOIN shop_working_hours h ON s.id = h.shop_id
WHERE
  CASE
    WHEN h.hours_close > h.hours_open THEN
      h.day_of_week = DAYOFWEEK(NOW()) AND
      CAST(NOW() AS time) >= h.hours_open AND CAST(NOW() AS time) < h.hours_close
    ELSE
      h.day_of_week = DAYOFWEEK(NOW() - 1) AND
      CAST(NOW() AS time) >= h.hours_open OR CAST(NOW() AS time) < h.hours_close
  END

Если, однако, вы бы предпочли иметь несколько столбцов, таких как *_hours_open и *_hours_close для каждого дня недели в одной и той же таблице, то есть в таблице shop, то условие фильтрации, скорее всего, должно быть более сложный, может быть, что-то вроде этого:

SELECT s.*
FROM shop s
  CROSS JOIN (
    SELECT 1 AS day_of_week
    UNION ALL SELECT 2
    UNION ALL SELECT 3
    UNION ALL SELECT 4
    UNION ALL SELECT 5
    UNION ALL SELECT 6
    UNION ALL SELECT 7
  ) h
WHERE
  CASE h.day_of_week
    WHEN 1 THEN
      CASE
        WHEN s.mon_hours_close > s.mon_hours_open THEN
          h.day_of_week = DAYOFWEEK(NOW()) AND
          CAST(NOW() AS time) >= s.mon_hours_open AND
          CAST(NOW() AS time) < s.mon_hours_close
        ELSE
          h.day_of_week = DAYOFWEEK(NOW() - INTERVAL 1 DAY) AND
          CAST(NOW() AS time) >= s.mon_hours_open OR
          CAST(NOW() AS time) < s.mon_hours_close
      END
    WHEN 2 THEN
      CASE
        WHEN s.tue_hours_close > s.tue_hours_open THEN
        …  /* same for Tuesday */
      END
    …  /* and for all the other days of week */
  END
1 голос
/ 04 июня 2011

В вашей таблице opening может быть три поля:

opening
    day_opens       <--- what day the shop opens
    hour_opens      <--- what hour the shop opens
    duration_open   <--- how many hours it stays open

Поэтому, если он открыт сейчас (или в определенный день и время), это будет условие, подобное:

WHERE (   day_opens = Day(NOW()) 
      AND hourOpens <= Hour(NOW())
      AND Hour(NOW()) < hourOpens + duration_open 
      )
   OR (   day_opens + 1 = Day(NOW())
      AND Hour(NOW()) < hourOpens + duration_open - 24
      )

или даже лучше в одном состоянии:

WHERE day_opens * 24 + hourOpens    <= Day(NOW()) * 24 + Hour(NOW())
  AND Day(NOW()) * 24 + Hour(NOW()) <  day_opens * 24 + hourOpens + hourOpens
1 голос
/ 04 июня 2011

Как насчет двух записей в вашей таблице магазинов за такие дни: одна с понедельника 09:00:00 - 11:59:59 и другая с вторника с 12:00:00 - 03:00 до 00:00

0 голосов
/ 05 июня 2011

Есть очень хорошие идеи: Доступен ли данный период бронирования?
(http://www.artfulsoftware.com/infotree/queries.php#576). Это помогло мне в похожей ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...