2011-05-27 2 views
2

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

таблиц выглядеть следующим образом:

  • Здание (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; 

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

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

+0

> Столбец Days содержит целое число, которое является произведением простых чисел, соответствующих дням недели (значение 23 означает, что событие происходит во вторник = 3 и в четверг = 7). Не было продукта 3 и 7 равным 21? Я смущен вашей методологией. – stefgosselin

+0

Да, спасибо, что поймали это. – gjarzab

+1

Рядом с дубликатом: http://stackoverflow.com/questions/6018445/get-list-with-start-and-end-values-from-table-of-datetimes –

ответ

0

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

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

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

Я должен указать на то, что хранение продукта простых чисел является одновременно вычислительным и дорогостоящим. Гораздо проще хранить сумму степеней двух (Mon = 1, Вт = 2, Wed = 4, Чт = 8, Fri = 16, Sat = 32, Sun = 64).

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

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

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

+1

Суммирующие значения 2^n выглядят намного лучше идея. Я не уверен, почему я не думал об этом в первую очередь. – gjarzab

+0

Да, только что заметил, что ваш единственный вопрос касается программирования на Android.Если вы используете это в SQLite-реализации Android, вам понадобится как можно больше эффективности в вашем алгоритме. В зависимости от устройства modulo может быть чрезвычайно дорогостоящим, поскольку многие встроенные устройства не имеют реального оборудования для операций деления. Гораздо лучше использовать 2^n, чтобы вы могли переключиться на побитовые и. –