За последние 24 часа нас посетили 16448 программистов и 1551 робот. Сейчас ищут 2048 программистов ...

Создание вложенного запроса

Тема в разделе "MySQL", создана пользователем masterlelik, 4 июл 2016.

  1. masterlelik

    masterlelik Активный пользователь

    С нами с:
    8 ноя 2008
    Сообщения:
    68
    Симпатии:
    0
    Просьба помочь создать запрос для следующей задачи.
    В БД есть строки со следующими полями:
    id | hotel_id | date_begin | date_end | price | currency
    И, например, значениями

    1 | 300 | 01.07.2016 | 09.07.2016 | 100 | usd
    2 | 300 | 10.07.2016 | 19.07.2016 | 200 | usd
    3 | 300 | 20.07.2016 | 29.07.2016 | 150 | usd

    Пользователь вводит в поисковой форме разброс дат с 05.07.2016 по 21.07.2016
    Количество дней: 7
    и сумму за проживания от 1000 $ до 1500 $

    В результате надо найти все отрезки дат подходящие под эти условия с подсчитанной суммой.
    Например, первый найденный отрезок будет: с 06.07.2016 по 12.07.2016 и стоимостью проживания 1000 $
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    В чём сложность? Там просто, псевдокод: WHERE date_begin > 05.07.2016 AND price < (если цена $100 за день, то дели 1500 на 7 и ищи чтобы цена была меньше)
     
  3. masterlelik

    masterlelik Активный пользователь

    С нами с:
    8 ноя 2008
    Сообщения:
    68
    Симпатии:
    0
    На 7 можно б было делить, если бы за любой день стоимость пребывания была бы одинаковой, но в разные промежутки цены разные
     
  4. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Там 100 usd за промежуток указана? От 01.07.2016 до 09.07.2016 указана или за 1 день?
     
  5. masterlelik

    masterlelik Активный пользователь

    С нами с:
    8 ноя 2008
    Сообщения:
    68
    Симпатии:
    0
    За один день.
    Поэтому для наглядности привел пример выборки для первого результата.
     
  6. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Тогда всё можно посчитать.

    Пишу одно и тоже третий раз:

    Если у нас есть промежуток времени и мы знаем цену за один его день, не за весь промежуток, так как это важно.
    При этом в базе цена указана тоже за 1 день для "свободного" промежутка.
    Мы можем из диапазона цены 1000 и 1500 вычислить сколько человек хочет потратить за 1 день. Максимум и минимум.
    Первым делом мы узнаём сколько дней в промежутке с 05.07.2016 по 21.07.2016 как указал человек. Будет 14 дней.
    Теперь 1000 делим на 14 и 1500 делим на 14, так мы узнаем минимум который человек хочет заплатить за 1 день на отдыхе и максимум.
    Потом мы просто составляем запрос и ищем в базе: date_begin > 05.07.2016 AND date_end < 21.07.2016 AND price < (1500 делим на 14) AND price > (1000 делим на 14)
    Так мы учтём все его параметры.
     
  7. masterlelik

    masterlelik Активный пользователь

    С нами с:
    8 ноя 2008
    Сообщения:
    68
    Симпатии:
    0
    Такое решение не всегда будет выбирать все данные.
    Вот пример.
    Есть первый день за 100$, второй за 110$ и третий за 90$.
    В среднем получается ровно 100$. Человек ищет отдых на 3 дня не выше 300$.
    И ему должно найти этот трех дневный отрезок. Но в вашем примере, где идет сравнение суточной цены с усредненным значением, не сможет найти второй день, т.к. 110$ это больше, чем среднее значение в 100$.
     
  8. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    нет у меня такого, только минимум и максимум

    Значит это уникальная ситуация, когда каждый новый день нужно переезжать в новый отель.
    Так не делают и это ты не упоминал.
     
  9. runner

    runner Активный пользователь

    С нами с:
    16 апр 2010
    Сообщения:
    343
    Симпатии:
    1
    Адрес:
    Ташкент
    1) Скорее всего нужный запрос для данной таблицы составить не получится.
    2) Обычно для заказа номера в отелях используется таблица доступности номеров rooms со структурой
    номер комнаты
    дата
    статус - занято/свободно
    стоимость

    Самое главное - чтобы была дата, а не диапазон дат

    В твоем случае таблицу можно преобразовать так:

    id | hotel_id | date_occupied | price | currency

    3) Запрос нужно сформировать в PHP:

    а) получить из 05.07.2016 по 21.07.2016 все возможные интервалы по 7 дней

    05.07.2016 по 11.07.2016
    06.07.2016 по 12.07.2016
    07.07.2016 по 13.07.2016
    08.07.2016 по 14.07.2016
    09.07.2016 по 15.07.2016
    10.07.2016 по 16.07.2016
    11.07.2016 по 17.07.2016
    12.07.2016 по 18.07.2016
    13.07.2016 по 19.07.2016
    14.07.2016 по 20.07.2016
    15.07.2016 по 21.07.2016

    б) Для каждого интервала составить запрос типа

    Код (Text):
    1. select '2016-07-05' as date_begin,'2016-07-11' as date_end,sum(price)  from rooms where date_occupied>='2016-07-05' and  date_occupied<='2016-07-11'
    2. group by  hotel_id
    3. having count(*) = 7 and sum(price)>=1000  and sum(price)<=1500
    в) объединяешь запросы с помощью UNION

    Для 4 первых интервалов

    Код (Text):
    1. (select '2016-07-05' as date_begin,'2016-07-11' as date_end,sum(price)  from rooms where date_occupied>='2016-07-05' and  date_occupied<='2016-07-11'
    2.  
    3. group by  hotel_id
    4.  
    5. having count(*) = 7 and sum(price)>=1000  and sum(price)<=1500 )
    6. UNION
    7. (select '2016-07-06' as date_begin,'2016-07-12' as date_end,sum(price)  from rooms where date_occupied>='2016-07-06' and  date_occupied<='2016-07-12'
    8.  
    9. group by  hotel_id
    10.  
    11. having count(*) = 7 and sum(price)>=1000  and sum(price)<=1500 )
    12. UNION
    13.  
    14. (select '2016-07-07' as date_begin,'2016-07-13' as date_end,sum(price)  from rooms where date_occupied>='2016-07-07' and  date_occupied<='2016-07-13'
    15.  
    16. group by  hotel_id
    17.  
    18. having count(*) = 7 and sum(price)>=1000  and sum(price)<=1500 )
    19. UNION
    20.  
    21. (select '2016-07-08' as date_begin,'2016-07-14' as date_end,sum(price)  from rooms where date_occupied>='2016-07-08' and  date_occupied<='2016-07-14'
    22.  
    23. group by  hotel_id
    24.  
    25. having count(*) = 7 and sum(price)>=1000  and sum(price)<=1500 )