Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите грамотно составить запрос 
:(
    Опции темы
letsgo
Дата 24.3.2010, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 17.2.2009

Репутация: нет
Всего: нет



Отлично. Первый вариант и последний я реализовал. А вот как быть со 2 и 3. 
Если в первом и последнем варианте возвращается стоимость тарифа и количество дней (секунд), то я просто перемножал и получал нужный мне результат.
А что во 2 и 3 варианте должно возвращаться? Две и более строки?
PM MAIL   Вверх
Fortop
Дата 24.3.2010, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



А почитать мой пример?
Там как раз 3й вариант приведен в качестве образца подсчета числа дней.


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
letsgo
Дата 25.3.2010, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 17.2.2009

Репутация: нет
Всего: нет



Цитата

А почитать мой пример?

Ну что ж. Огромное Вам спасибо. Не ожидал, что время генерации результата будет практически в 10 раз меньше по Вашему методу, чем с моими циклами.

Не посчитайте за наглость, но...
А как описать ситуацию, когда в запросе задаются параметры, скажем так несуществующего периода?
Допустим, у нас в базе содержится информация о стоимости тарифа в сутки для периода с 15.05.2010 по 31.05.2010, стоимость тарифа в июне не дана.
Но пользователь всё-таки запрашивает стоимость тарифа с 25.05.2010 по 03.06.2010, допустим. Как лучше оформить ограничение в запросе, когда $date_finish (в нашем случае 03.06.2010) в базе не существует? Бывает, что пользователь запрашивает стоимость тарифа на период, к примеру, с 15.05.2010 по 10.06.2010, а в базе по каким-то причинам, есть периоды 15.05.2010 - 05.06.2010 и 08.06.2010 - 31.06.2010
Т.е. случае разные бывают, когда нет нескольких дней или естьь величина тарифа до какого-то числа, а дальше нет. Это всё нужно предусмотреть, чтобы пользователю не выдавался результат меньше. В этих случаях должен нуль возвращаться.

Сейчас, я, к сожалению, вижу только одно решение, если возвращаемое количество days меньше, чем оно должно быть, то возвращать 0.  
Но плохо, что в этом случае, придётся обходить все строки, полученные при запросе.
Насколько это правильно? Или это лучше сделать в самом запросе? 

Это сообщение отредактировал(а) letsgo - 25.3.2010, 11:50
PM MAIL   Вверх
Fortop
Дата 25.3.2010, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(letsgo @  25.3.2010,  10:14 Найти цитируемый пост)
Не ожидал, что время генерации результата будет практически в 10 раз меньше по Вашему методу, чем с моими циклами.

Основная причина - это количество запросов к БД.

Цитата(letsgo @  25.3.2010,  10:14 Найти цитируемый пост)
Допустим, у нас в базе содержится информация о стоимости тарифа в сутки для периода с 15.05.2010 по 31.05.2010, стоимость тарифа в июне не дана.
Но пользователь всё-таки запрашивает стоимость тарифа с 25.05.2010 по 03.06.2010, допустим.

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

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

Цитата(letsgo @  25.3.2010,  10:14 Найти цитируемый пост)
 В этих случаях должен нуль возвращаться.

Ноль за весь промежуток? или только за отсутствующие дни?
Если второе, то запрос это и делает (точнее он просто не считает отсутствующие дни).
Если первое, то необходимо пересмотреть сам запрос.


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
letsgo
Дата 25.3.2010, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 17.2.2009

Репутация: нет
Всего: нет



Цитата

Т.е. что мы должны делать с днями отсутствующим в базе?
Игнорировать? Взять тариф из периода раньше? Или периода позже?

Игнорировать нельзя. Если стоимости тарифа за какой-то день в базе нет, но в периоде запроса пользователя этот день присутствует, мы должны вернуть однозначный нуль. Даже, если период заданный пользователем равен 365 дням, а в базе нет данных только об одном дне, всё равно возвращать нуль.

Цитата

Ноль за весь промежуток? или только за отсутствующие дни?

именно за весь промежуток. 
Если у нас с 01.05.2010 по 15.05.2010 в базе есть данные о стоимости тарифа, а с 16.05.2010 и далее уже нет, то на запрос пользователя о стоимости тарифа с 01.05.2010 по 17.05.2010 мы должны вернуть именно нуль, а не стоимость тарифа с 01.05.2010 по 15.05.2010

Это сообщение отредактировал(а) letsgo - 25.3.2010, 18:10
PM MAIL   Вверх
Fortop
Дата 25.3.2010, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(letsgo @  25.3.2010,  17:08 Найти цитируемый пост)
 Даже, если период заданный пользователем равен 365 дням, а в базе нет данных только об одном дне, всё равно возвращать нуль.

Ну это несколько грустно.
А в чем логика такого поведения? Не поделитесь?

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




--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
letsgo
Дата 25.3.2010, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 17.2.2009

Репутация: нет
Всего: нет



Цитата

А в чем логика такого поведения? Не поделитесь?

Стоимость тарифа - это доллары. Суммы получаются, иногда внушительные smile
Возвращаемый результат этого запроса умножается еще на несколько значений (различные проценты, коэфф. и т.д.), в итоге пользователь видит полную стоимость той услуги/товара, которую он запрашивает.
Соответственно, если период пропущен, значит окончательная стоимость будет просчитана неверно, а значит компания может уйти в минус при совершении сделки по продажи услуги. Конечно, можно проверять потом еще и вручную сделанный заказ, но тогда теряется весь смысл автоматизации. К тому же, недовольные клиенты, уверен, будут возмущаться, ведь на сайте указывается одна цена, а в итоге получается совершенно другая.

Цитата

Что же касается решения задачи, то придется сделать еще один запрос для проверки непрерывности сетки тарифов для указанного периода.

А как считаете, что будет быстрее?
Делать еще один запрос или же проверять разницу: "количество дней, которое возвращает запрос" - "количество дней, заданное пользователем"? Если количество дней не совпадает, следовательно возвращаем нуль.

Именно так, я сейчас эту "дырку" в алгоритме и заткнул, но минус в том, что всё равно приходится совершать лишние манипуляции при обработке возвращаемого результата. Если подскажите, как лучше организовать подобный запрос, с удовольствием попробую на скорость.

Это сообщение отредактировал(а) letsgo - 25.3.2010, 19:05
PM MAIL   Вверх
Fortop
Дата 25.3.2010, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(letsgo @  25.3.2010,  18:02 Найти цитируемый пост)
Соответственно, если период пропущен, значит окончательная стоимость будет просчитана неверно, а значит компания может уйти в минус при совершении сделки по продажи услуги.

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

Цитата(letsgo @  25.3.2010,  18:02 Найти цитируемый пост)
А как считаете, что будет быстрее?
Делать еще один запрос или же проверять разницу: "количество дней, которое возвращает запрос" - "количество дней, заданное пользователем"? Если количество дней не совпадает, следовательно возвращаем нуль.

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

Код

set profiling = 1;
//один запрос;
//второй запрос;
show profiles;


Цитата(letsgo @  25.3.2010,  18:02 Найти цитируемый пост)
я сейчас эту "дырку" в алгоритме

Предусмотренное поведение не является дырой.


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
letsgo
Дата 27.7.2010, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 17.2.2009

Репутация: нет
Всего: нет



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

В существующую таблицу, которая указана в первом посте добавляются два столбца (`valid_from`, `valid_to`), которые содержат в себе информацию о периодах, в которые действует данный тариф.
Объясню на примере.
Раньше у нас в таблице были следующие записи (для упрощения время в UNIX формате запишу в обычном виде)
Код

id | idtariff |  date_start     | date_finish | price | 
1        5        25.07.2010       12.08.2010   25
2        5        13.08.2010       16.08.2010   30


Чтобы рассчитать стоимость тарифа в указанной выше таблице, нам необходимо воспользоваться запросом, который мне подсказали в данном топике. Он прекрасно работает, к нему нареканий нет, но с учётом добавления двух новых столбцов, о которых я говорил выше, данный запрос становится ошибочным. Что мы имеем сейчас?

Код

id | idtariff |  valid_from  |    valid_to    | date_start     |   date_finish   | price | 
1        5                                       14.07.2010      31.07.2010          25
2        5        06.07.2010      22.08.2010     29.07.2010      31.07.2010          21
3        5                                       01.08.2010      22.08.2010          23
4        5        06.07.2010      22.08.2010     01.08.2010      22.08.2010          20


Представим, что сейчас на дворе 1 июля 2010 и мы хотим узнать тарифа с idtariff=5 c 28.07.2010 по 03.08.2010
Тогда нам необходимо взять в расчёт следующие периоды:
Строка с ID=1 (14.07.2010      31.07.2010): Мы берем 4 дня. 25*4=100
Строка с ID=3 ( 01.08.2010      22.08.2010): Мы берем 3 дня. 23*3=69
Получается стоимость тарифа = 169

Если мы хотим узнать стоимость тарифа, который будет действовать с 28.07.2010 по 03.08.2010, 
в промежуток времени между 06.07.2010 и по 22.08.2010, то нам необходимо взять следующие строки:
Строка с ID=1 (14.07.2010      31.07.2010): Мы берем 1 день. 25*1=25
Строка с ID=2 (14.07.2010      31.07.2010): Мы берем 3 дня. 21*3=63
Строка с ID=4 (06.07.2010       22.08.2010): Мы берем 3 дня. 20*3=60
Получается стоимость тарифа = 148

В общем, как понимаете сложностей много (по крайней мере для меня). Как все эти подробности учесть и при этом минимизировать
количество запросов к БД.
Буду благодарен за помощь и с радостью отвечу на все-все-все вопросы....
Заранее спасибо, коллеги

Это сообщение отредактировал(а) letsgo - 27.7.2010, 13:11
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0812 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.