Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Выборка по диапазону дат
 
 автор: Хулиган   (12.12.2009 в 20:44)   письмо автору
 
 

Здравствуйте!
Вопрос по оператору <=

SELECT acc.date, acc.code, m.product, m.unit,
acc.count, acc.state, acc.seller
FROM `acc_6BC76F81` AS acc, `main` AS m
WHERE m.code=acc.code AND
acc.date>= '2009-11-03' AND
acc.date<= '2009-11-12'
ORDER BY date ASC, product ASC;


В результате (я так полагаю), должны быть все записи с 2009-11-03 по 2009-11-12 включительно.
Но на деле записи за 2009-11-12 не выбираются. Оператор <= действует как <
Если обе даты установить в 2009-11-03, то вообще ни одной записи не выводится.

Что у меня неправильно?

  Ответить  
 
 автор: Valick   (12.12.2009 в 20:50)   письмо автору
 
   для: Хулиган   (12.12.2009 в 20:44)
 

BETWEEN
запятая

  Ответить  
 
 автор: Trianon   (12.12.2009 в 21:06)   письмо автору
 
   для: Хулиган   (12.12.2009 в 20:44)
 

видимо acc.date хранит не только дату, но и время.

  Ответить  
 
 автор: Хулиган   (12.12.2009 в 22:02)   письмо автору
 
   для: Trianon   (12.12.2009 в 21:06)
 

Да, точно, в БД поле DATETIME, а в запросе только DATE.
Прилепил к датам строки ' 00:00' и ' 23:59' соответственно и работает.
С BETWEEN тоже работает.

А вот с запятой не понял, почему её убирать надо? Без запятой между именами таблиц не работает:

MySQL error: 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 '`main` AS m WHERE m.code=acc.code AND acc.date BETWEEN '2009-11-03 00:00' AND '2' at line 1

Или отказавшись от запятой нужно перейти к JOIN?

P.S.

Заглянул в учебник, как советовалось по ссылке выше, там с запятыми перечисляются имена таблиц:

mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
    -> FROM pet AS p1, pet AS p2
    -> WHERE p1.species = p2.species AND p1.sex = "f" AND p2.sex = "m";

  Ответить  
 
 автор: Trianon   (12.12.2009 в 22:21)   письмо автору
 
   для: Хулиган   (12.12.2009 в 22:02)
 

>Да, точно, в БД поле DATETIME, а в запросе только DATE.
>Прилепил к датам строки ' 00:00' и ' 23:59' соответственно и работает.
23:59:59

>А вот с запятой не понял, почему её убирать надо?

А я говорил, что её нужно убирать?
Потому что Вы не знаете что она означает и как работает.

>Без запятой между именами таблиц не работает:

>Заглянул в учебник, как советовалось по ссылке выше, там с запятыми перечисляются имена таблиц:
>mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
> -> FROM pet AS p1, pet AS p2
> -> WHERE p1.species = p2.species AND p1.sex = "f" AND p2.sex = "m";

и что?
Это противоречит моему утверждению?

К слову сказать, к Вашему случаю запятую припомнил не я.
У Вас явного кошмара нет.

  Ответить  
 
 автор: Хулиган   (13.12.2009 в 00:41)   письмо автору
 
   для: Trianon   (12.12.2009 в 22:21)
 

Про запятую это Вы сказали, что "надо расстреливать деревянными пулями" применяющих её при перечислении таблиц в FROM.

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

Если Вы считаете иначе, то объясните, почему. Я ничего в учебнике, что могло хоть как-то пролить свет на Вашу точку зрения, не нашёл.
Почем же нельзя применять запятую при перечислении таблиц в FROM?
Если можно, но в каких-то конкретных случаях, может объясните, когда можно, а когда нет?

P.S.
23:59:59 - да, конечно же.

  Ответить  
 
 автор: Trianon   (13.12.2009 в 01:07)   письмо автору
 
   для: Хулиган   (13.12.2009 в 00:41)
 

>Про запятую это Вы сказали, что "надо расстреливать деревянными пулями" применяющих её при перечислении таблиц в FROM.

Сказал. Потому что подавляющее большинство тех, кто её применяют, понятия не имеют ни что делают, ни что она - запятая - обозначает.

>Искать в учебнике "что значит запятая" бессмысленно.

А искать, что значит JOIN, смысл есть?

>В моём понимании запятая просто разделяет перечисляемые значения и не более того. И применительно к перечисляемым таблицам её смысл точно такой же, как и например при перечислении полей, по которым идёт выборка.

Это категорически неверно.
Это примерно как утверждать, что в выражении $s = 2 * 3.14159 * $r; звездочка просто разделяет цифры.

>Если Вы считаете иначе, то объясните, почему. Я ничего в учебнике, что могло хоть как-то пролить свет на Вашу точку зрения, не нашёл.

Видимо Вы читали такой учебник, автора которого нужно расст... и далее по тексту.
А хороший учебник объясняет, что операция запятая является не разделителем элементов списка, а табличной операцией, и что запятая, как операция (она же JOIN без условий, она же CROSS JOIN) декартово перемножает таблицы , то есть строит из двух таблиц одну большую, в которой столбцов столько же суммарно столбцов в исходных таблицах, а строк столько, чему равно произведение количества строк одной исходной на количество строк другой исходной. Значения полей этой огромной таблицы заполнены всевозможными сочетаниями строк этих двух таблиц.
Затем, если в списке стоит вторая запятая, эта таблица декартово домножается на еще одну, и т.д.

Отбор весьма небольшого количества правильных строк из всего этого бардака происходит лишь тогда, когда позже в хвосте запроса стоит условие отбора WHERE -
в Вашем случае WHERE m.code=acc.code
если Вы попробуете его убрать - получите всю кашу оптом.

>Почем же нельзя применять запятую при перечислении таблиц в FROM?
>Если можно, но в каких-то конкретных случаях, может объясните, когда можно, а когда нет?

Можно тогда, когда Вы понимаете, с чем в итоге приходится работать.

По моему же глубокому убеждению, в подобных случаях вместо запятой следует применять операцию t1 JOIN t2 ON условие_соответствия_строк
Это и проще для понимания и аккуратнее в записи.

  Ответить  
 
 автор: admiral   (13.12.2009 в 01:58)   письмо автору
 
   для: Trianon   (13.12.2009 в 01:07)
 

>По моему же глубокому убеждению, в подобных случаях вместо запятой следует применять >операцию t1 JOIN t2 ON условие_соответствия_строк
>Это и проще для понимания и аккуратнее в записи.
И для производительности тоже имеет результативность по сравнению с перечеслением имен через запятую?

  Ответить  
 
 автор: Trianon   (13.12.2009 в 11:51)   письмо автору
 
   для: admiral   (13.12.2009 в 01:58)
 

А Вы специалист по производительности SQL-запросов? Почему Вас уже волнует этот вопрос?

Я сталкивался с тем, что в некоторых случаях оптимизатор MySQL был не в состоянии перестроить декартово произведение с фильтром в соединение по условию, и серверу приходилось создавать полную таблицу и лишь потом отфильтровывать нужные строки.

  Ответить  
 
 автор: Хулиган   (13.12.2009 в 03:47)   письмо автору
 
   для: Trianon   (13.12.2009 в 01:07)
 

Вытянули таки из Вас клещами, в чем дело.
Проверил - действительно без фильтрации по одинаковым полям в таблицах (m.code=acc.code ) количество строк в результате равно произведению строк в таблицах. Столбцы уже не стал проверять.
Спасибо за информацию.

Надеюсь, хотя бы в случае перечисления полей в запросе запятая является просто разделителем, а не множителем, как в случае перечисления таблиц :)

  Ответить  
 
 автор: Trianon   (13.12.2009 в 11:46)   письмо автору
 
   для: Хулиган   (13.12.2009 в 03:47)
 

При чем тут клещи?
Я об этом неоднократно писал на форуме.
И не только я.

  Ответить  
 
 автор: Хулиган   (13.12.2009 в 17:48)   письмо автору
 
   для: Trianon   (13.12.2009 в 11:46)
 

Мне попалась только одна тема, и там вопрос не был раскрыт. Хотя возможно где-то в других темах Вы упоминали об этом.

У меня ещё один вопрос по теме запятой и join:

Как я понял из всего сказанного выше, при использовании запятой создается группа из 30000 строк (5000 в main и 6 в acc), из которой потом выбираются 3 (удовлетворяющих условию BETWEEN).
А при использовании join должен создаваться набор из 6 записей, удовлетворяющих условию объединения (ON m.code=acc.code), из которых затем выбираются 3.
Исходя из этих посылок (если они верны), я ожидаю значительного прироста в производительности.
Но бенчмарк при переходе от запятой к join показывает прирост производительности всего 4%.
Отсюда делаю вывод: процесс выполнения запроса делится на две стадии:
1. Создание промежуточного набора
2. Выборка из созданного набора.
Увеличение скорости происходит только на второй стадии. А первая стадия занимает львиную долю времени и примерно равна как для запятой, так и для join.
Если ввести такое понятие, как скорость добавления записи в промежуточный набор (sec/row), то:
В случае с запятой промежуточный набор строится быстро (ничего фильтровать не надо, просто тупо перемножать таблицы) , но он большой.
В случае с join время на одну запись промежуточного набора значительно больше (нужно искать записи по условию), но за счёт малого количества join подтягивается к запятой по общему времени.
Грубо говоря, запятая добавляет строки быстро, но их много. join добавляет медленно, но строк мало.
Это так? Или я неправильно рассуждаю?

  Ответить  
 
 автор: Trianon   (13.12.2009 в 17:58)   письмо автору
 
   для: Хулиган   (13.12.2009 в 17:48)
 

>У меня ещё один вопрос по теме запятой и join:
>Исходя из этих посылок (если они верны), я ожидаю значительного прироста в производительности.

Это вопрос не по теме запятой и JOIN .
Это вопрос по теме производительности запросов и здесь, чтобы давать какие-либо комментарии, компетентен недостаточно. Алгоритмы работы и код оптмизатора MySQL я не изучал.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования