Объедините несколько запросов доступности номеров в один - PullRequest
4 голосов
/ 11 февраля 2011

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

У меня есть таблица доступности номеров, где в каждой записи указано доступное количество номеров на дату.Он имеет следующий формат:

  • room_availability_id (PK)
  • room_availability_rid (fk_room_id)
  • room_availability_date (2011-02-11)
  • room_availability_number (количество доступных номеров)

Проблема в том, чтобы получить список номеров, доступных для КАЖДОГО из предоставленных дней.Когда я использую IN () примерно так:

WHERE room_availability_date IN('2011-02-13','2011-02-14','2011-02-15')
AND room_availability_number > 0

Если у 14-го есть доступность 0, это все равно дает мне другие 2 даты.Но мне нужен только номер room_id, когда он доступен на ВСЕХ трех датах.

Скажите, пожалуйста, есть способ сделать это в MySQL, кроме запроса каждой комбинации дата / комната / доступность отдельно (это то, что делаетсясейчас :-()

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

Заранее спасибоза любые мысли!

Ответы [ 3 ]

4 голосов
/ 11 февраля 2011

Вам необходимо создать запрос на группировку по идентификатору комнаты, а затем проверить, есть ли доступность на каждую дату, что можно сделать с помощью предложения has.Оставление предиката предложения where для room_availability_date поможет сохранить эффективность запроса (поскольку индексы и т. Д. Не могут быть легко использованы с предложением has).

SELECT 
    room_availability_rid

WHERE room_availability_date IN ('2011-02-13','2011-02-14','2011-02-15')
  AND room_availability_number > 0

GROUP BY room_availability_rid 

HAVING count(case room_availability_date when '2011-02-13' THEN 1 END) > 0
   AND count(case room_availability_date when '2011-02-14' THEN 1 END) > 0
   AND count(case room_availability_date when '2011-02-15' THEN 1 END) > 0
3 голосов
/ 11 февраля 2011

Я думаю, что могу улучшить ответ а'ра:

SELECT 
    room_availability_rid, count(*) n

WHERE room_availability_date IN ('2011-02-13','2011-02-14','2011-02-15')
  AND room_availability_number > 0

GROUP BY room_availability_rid 

HAVING n=3

Редактировать: Это, конечно, предполагает, что на номер в день входит только одна запись в таблице. Это правильное предположение?

1 голос
/ 11 февраля 2011

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

Это даст вам список дат, для которых доступна каждая комната:

select `room_availability_rid`,group_concat(`room_ availability_date`) as `datelist`
       from `table` where room_availability_number>0 
       group by `room_availability_rid`

Затем мы можем добавить предложение, чтобы получить номера, доступные на все нужные нам даты:

select `room_availability_rid`,group_concat(`room_ availability_date`) as `datelist`
        from `table` where room_availability_number>0
        group by `room_availability_rid`
        having find_in_set('2011-02-13',`datelist`) and
               find_in_set('2011-02-14',`datelist`) and
               find_in_set('2011-02-15',`datelist`)

Это должно работать.Проверьте это для меня, не так ли?:)

...