Народ, прошу помощь умной мыслью... На какие таблицы разбить данные чтоб потом можно было адекватно считать: Есть отель(не один но пока не принципиально), цена номера за сутки в период с-по: date_from | date_till | price 2012-01-01 | 2012-01-10 | 50 2012-01-11 | 2012-03-15 | 30 2012-03-16 | 2012-07-02 | 60 Нужно посчитать стоимость проживания например с 2012-01-05 по 2012-01-13 Все что пока придумал: 1) разбить данные на 365 строк, а потом делать запрос SELECT SUM(price) from table WHERE date BETWEEN 2012-01-05 AND 2012-01-13 в этом случае 365 дней * 500 отелей = 182 500 строк однотипной информации (а еще надо думать над високосными годами) 2) Писать данные прямо как есть, а потом из PHP делать запрос WHILE-ом отдельно на каждую дату SELET price FROM table WHERE date_from <="2012-01-05" AND date_till >= "2012-01-05" SELET price FROM table WHERE date_from <="2012-01-05" AND date_till >= "2012-01-05" ... и суммировать price в PHP. Что при выборке 50 отелей на 14 дней получается 700 запросов...
Re: Помогите со структурой БД (работа с датами) можно обойтись и без разбиения на 365 строк. хотя идея любопытная ))) применить что-то типа select sum(num_days * price) где num_days будет вычисленным значением из подзапроса по датам если сам не догонишь, я попробую протестировать это в реальных таблицах чуть позже…
Re: Помогите со структурой БД (работа с датами) вот что выродилось: Код (Text): /* Эта хитрая хрень с DATEDIFF дает нам количество дней */ SELECT SUM((DATEDIFF(rc.d2, rc.d1) + 1) * rc.price) AS cost FROM ( SELECT GREATEST(:dfrom, rp.d_from) AS d1, LEAST(:dto, rp.d_to) AS d2, rp.price FROM `room_prices` AS rp WHERE /* эта хрень даст нам пересечение цены за нужный диапазон дат. выборка быстрая по Primary Key */ (rp.hotel_id = :hotel AND rp.room_no = :room) AND (rp.d_from BETWEEN :dfrom AND :dto OR rp.d_to BETWEEN :dfrom AND :dto) ) AS rc предполагается, что таблица room_prices полностью и без дыр покрывает нужные периоды. первичный ключ (hotel_id, room_no, d_from) Добавлено спустя 15 минут 48 секунд: Например: room_prices(hotel_id, room_no, d_from, d_to, price): Код (Text): 1 101 2012-01-01 2012-01-07 50.00 1 101 2012-01-08 2012-01-31 25.00 1 101 2012-02-01 2012-02-29 20.00 фигачим запрос по комнате 101 в первом отеле с 3 по 15 января. это пересекает два периода в нашей таблице цен Код (Text): SELECT SUM((DATEDIFF(rc.d2, rc.d1) + 1) * rc.price) AS cost FROM ( SELECT GREATEST(DATE '2012-01-03', rp.d_from) AS d1, LEAST(DATE '2012-01-15', rp.d_to) AS d2, rp.price FROM `room_prices` AS rp WHERE (rp.hotel_id=1 AND rp.room_no='101') AND (rp.d_from BETWEEN DATE '2012-01-03' AND DATE '2012-01-15' OR rp.d_to BETWEEN DATE '2012-01-03' AND DATE '2012-01-15') ) AS rc внутренний подзапрос вернет: Код (Text): 2012-01-03 2012-01-07 50.00 2012-01-08 2012-01-15 25.00 общий итог в sum(): 450.00 == 5*50+8*25 дамп базы: http://zalil.ru/34048536
Re: Помогите со структурой БД (работа с датами) Только собрался писать про эту самую хитрую единицу, обновился а ты ее присобачил уже У меня правда мысль куда-то опять завернула не в ту степь и получилось Код (Text): ... SUM((TO_DAYS(rc.d2)+1-TO_DAYS(rc.d1))*price) AS cost ... в твоем варианте красивее А вот за Огромное спасибо