SQL - Поиск открытых пространств в расписании - PullRequest
2 голосов
/ 27 мая 2011

Я работаю с базой данных SQLite, и у меня есть три таблицы, описывающие здания, комнаты и запланированные события.

Таблицы выглядят так:

  • Здание (ID, Имя)
  • Номер (ID, BuildingID, номер)
  • События (ID, BuildingID, RoomID, дни, s_time, e_time)

То есть каждое событие связано со зданием и комнатой. Столбец Days содержит целое число, которое является произведением простых чисел, соответствующих дням недели (значение 21 означает, что событие происходит во вторник = 3 и в четверг = 7).

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

Вот что у меня есть:

SELECT Rooms.Number 
FROM Rooms
INNER JOIN Buildings on ( Rooms.BuildingID = Buildings.ID )
WHERE 
  Buildings.Name = "BuildingName"

EXCEPT

SELECT Events.RoomID
FROM Events
INNER JOIN Buildings on ( Events.BuildingID = Buildings.ID )
WHERE
  Buildings.Name = "BuildingName" AND
  Events.days & 11 = 0 AND
  time("now", "localtime" BETWEEN events.s_time AND events.e_time;

Здесь я нахожу все комнаты для определенного здания, а затем удаляю комнаты, в которых в данный момент запланировано событие.

Я с нетерпением жду всех полезных советов / комментариев.

1 Ответ

0 голосов
/ 15 августа 2011

Если вы храните даты как произведение простых чисел, оператор modulo (%) может быть более полезным:

SELECT * FROM Events
INNER JOIN Buildings on (Events.BuildingID = Buildings.ID)
WHERE
    (Events.Days % 2 = 0 AND Events.Days % 5 = 0)

Выбирает события, происходящие в понедельник или среду.

Я должен отметить, что хранение произведения простых чисел является и вычислительным, и дорогостоящим.Намного проще хранить сумму степеней двух (пн = 1, вт = 2, ср = 4, четверг = 8, пт = 16, сб = 32, солнце = 64).

Наибольшее возможное значениедля вашей текущей реализации 510 510.Наименьший тип данных для хранения такого числа - int (32 бита на строку), а для извлечения закодированных данных требуется до 7 операций по модулю (%).

Наибольшее возможное значение для метода суммирования 2 ^ n127, который может быть сохранен в виде tinyint (8 битов на строку) и для извлечения закодированных данных будет использоваться побитовое и (&), что несколько дешевле (и, следовательно, быстрее).

Вероятно, не проблема для того, что вы 'Вы работаете с ним, но это хорошая привычка выбирать тот метод, который дает вам наилучшее пространство и эффективность, иначе вы столкнетесь с серьезными проблемами, если ваше решение будет реализовано в больших масштабах.

...