Задавайте вопросы, мы ответим
Вы не зашли.
Добрый день ВСЕМ!
Помогите, или подскажите как дописать запрос, я на одном месте завис, и не знаю что делать, знания СКЛ иссякли ))
Есть таблицы users, main, plans, periods, tarifs, hollidays
-------------------------------------
таблица users
------------------
| id | uid |
------------------
| test | 123 |
таблица main
----------------
| p_id | uid |
----------------
| 2 | 123 |
таблица plans
--------------------
| id | p_id |
--------------------
| 2 | 23 |
таблица periods
-----------------------------------------------------
| id | interval_id | begin | end | day |
-----------------------------------------------------
| 2 | 45 | 10:00:00 | 24:00:00 | 1 |
таблица tarifs
------------------------------------
| in_speed | out_speed |interval_id |
------------------------------------
| 128 | 128 | 3 |
таблица hollidays
-----------
| day |
-----------
| 3-8 |
| 1-7 |
| 2-23 |
В общем затор у меня на выборе нужного дня
Так-как в таблице periods может быть 1. day=1..7 -первый запрос 2. day=0 -второй запрос 3. day =0 и 8 где 8-праздинчный день
4. 1..8 каждый день + праздничные
Нужен запрос который работал бы при таких условиях:
Первый запрос: если periods.day например 1-понедельник, 3-среда, тогда учитывал эти дни по DATE_FORMAT( NOW() + INTERVAL 1 DAY, '%w' ) = per.day
Второй запрос: если periods.day=0 тоесть все дни - тогда просто смотрел на интервалы времени
Третий запрос: если в periods.day кроме первых двух вариантов есть еще 8 -праздничные дни, тогда смотрел в таблицу hollidays и сравнивал с текущей датой (месяц-день) если нету делал первый или второй вариант запроса
----------------------------------------
Первый запрос: Если есть в таблице periods несколько дней тогда выбирается то поле где день равняется сегодняшнему дню
AND DATE_FORMAT( NOW() + INTERVAL 1 DAY, '%w' ) = per.day
и происходит поиск скорости
Неактивен
Попробуйте заменить
Отредактированно deadka (17.05.2011 16:30:11)
Неактивен
Я добавил Ваш вариант в запрос но он выдает ошибку, также я делаю пробный запрос только с вашим вариантом таже ошибка
Неактивен
Приведите пожалуйста дампы таблиц intervals и periods (show create table ) и данные из таблиц).
Неактивен
я в предыдущем сообщении не правильно написал ответ, должно быть
select per.day from periods as per where
per.day IN (if (per.day=0,0,select per.day from periods per where DATE_FORMAT( NOW() + INTERVAL 1 DAY, '%w' ) = intv.day ))
[3] ERROR_SQL /select per.day from periods as per where
per.day IN (if (per.day=0,0,select per.day from periods as per where DATE_FORMAT( NOW() + INTERVAL 1 DAY, '%w' ) = per.day )) / You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select per.day from periods as per where DATE_FORMAT( NOW() + INTERVAL 1 DAY' at line 2/
Неактивен
В такой форме запрос работает - некорректно алиасы стояли.
Отредактированно deadka (18.05.2011 14:58:51)
Неактивен
Спасибо запрос работает но только для таких случаев
day=1..7 (тоесть любой день недели)
day=0 (все дни)
а если
day=0,8 (все +праздничные) и сегодня праздник, тогда не работает
или day=1,8 (Воскресенье +праздничные) и сегодня праздник, тогда не работает
Надо еще както учесть если в интервалах кроме первых двух случаев, есть еще day='8' тогда проверить таблицу праздников есть ли там сегодняшняя дата, если есть тогда выбрать скорость которая прописана для 8
таблица hollidays
Неактивен
Итак, мы убедились, что конструкция if в запросе работает - при этом можно что в случае выполнения, что невыполнения условия в if выбирать что число, что результат запроса .
Далее никто не мешает несколько усложнить логику в if condition.
Например:
Неактивен
Большое спасибо. Но есть два "но"
1. При
Неактивен
Ну так и составьте условие if нужным образом.
Что-то вроде
Отредактированно deadka (19.05.2011 00:52:01)
Неактивен
Спасибо, почти разобрался, только еще вопросик
если в таблице
tp_id begin end tarif day id
100 00:00:00 24:00:00 0 4 192
100 00:00:00 24:00:00 0 3 191
100 00:00:00 24:00:00 0 5 195
100 00:00:00 24:00:00 0 8 196
и когда делаю так
Неактивен
Если выборка даёт несколько рядов, а вам нужен только один, то да - limit годится для того, чтобы отсечь лишнее.
А почему нужно, чтобы именно строка с day=8 была выбрана? Чем строка с day = 5 не годится?
Неактивен
пробовал разные варианты считаю что должен быть такой запрос :
ищет intv.day В ( если intv.day=8 тогда проверяет таблицу holidays если там есть нужная дата, тогда intv.day=8 если нету тогда подзапрос (если intv.day=0 тогда 0 если нет тогда поиск текущей даты) если intv.day не равняется 8 тогда также проверка intv.day=0 тогда 0 если нет тогда поиск текущей даты )
вот как оно выглядит:
Неактивен
даже не так
Отредактированно moose (19.05.2011 14:19:56)
Неактивен
Таблицу intervals Вы ранне не упоминали.
Приведите
show create table intervals;
show create table holidays;
И дампы этих таблиц плиз в виде insert into intervals... и insert into holidays.
Чтоб полностью воссоздать .
Что еще - проследите за тем, чтобы запросы, который в if возвращали одну строку, у Вас это не очевидно в нескольких подзапросах.
(select count(*) from holidays where DATE_FORMAT( NOW(), '%c-%e' ) = day)>0, 8,
Тут точно = day?
может быть = intv.day?
Неактивен
deadka написал:
Таблицу intervals Вы ранне не упоминали.
Это тоже самое что и periods я просто так ее назвал
(select count(*) from holidays where DATE_FORMAT( NOW(), '%c-%e' ) = day)>0,
Выводит все верно
Дамп
Неактивен
Нда, запросец, конечно, получился такой, что без поллитры, в крайнем случае без форматирования табами не разберешься.
Ваш запрос не компилируется потому, что в нем со скобками непорядок.
Так компилируется.
Отредактированно deadka (19.05.2011 21:16:33)
Неактивен
Большое СПАСИБО deadka! Вы настоящий друг! )
конечный запрос имеет вид
Неактивен
Пожалуйста . Касательно оптимизации - если наличествуют индексы на тех полях, по которым производится join, то вроде и так ничего навскидку не назову.. И не забудьте в коде поставить к нему подробный комментарий .
Отредактированно deadka (20.05.2011 15:19:00)
Неактивен
Спасибо, коментарий - обязательно))
Неактивен