Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Выборка из бд по дате
Форумы портала PHP.SU » » Работа с СУБД » Выборка из бд по дате

Страниц (1): [1]
 

1. lawer85 - 06 Января, 2016 - 16:29:17 - перейти к сообщению
Есть таблица с полем timestamp. Туда записывается дата + время типа так 2016-01-03 20:16:29

Как мне вытащить все записи одной даты конкретной даты?

Запрос такого вида не проходит

CODE (SQL):
скопировать код в буфер обмена
  1. "SELECT id FROM activities WHERE created_at='2016-01-03'"
2. re_nat - 06 Января, 2016 - 16:41:31 - перейти к сообщению
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id FROM activities WHERE DATE_FORMAT(created_at, '%Y-%m-%d')='2016-01-03'
3. lawer85 - 06 Января, 2016 - 17:02:43 - перейти к сообщению
Спасибо
4. Мелкий - 06 Января, 2016 - 17:03:40 - перейти к сообщению
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id FROM activities WHERE created_at='2016-01-03'

После приведения типов становится
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id FROM activities WHERE created_at='2016-01-03 00:00:00'

Понятно, почему не работает как ожидается?

Вариант
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id FROM activities WHERE DATE(created_at)='2016-01-03'

Или DATE_FORMAT, как предлагает re_nat дадут нужный результат. Вот только вопрос цены.
Эти запросы в принципе не смогут использовать индекс по created_at.
И если для нормальных СУБД можно сделать индекс по функции, то в mysql - никак.

Лучше немного усложнить клиентскую часть и генерировать запрос
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id FROM activities WHERE created_at >= '2016-01-03' AND created_at < '2016-01-04'

Надо глянуть explain'ы, но по идее оптимизатор не должен тупить и с простым
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id FROM activities WHERE created_at >= '2016-01-03' AND created_at < '2016-01-03' + interval 1 day
5. lawer85 - 06 Января, 2016 - 17:13:23 - перейти к сообщению
Я понимаю почему мой вариант не работал. Я предполагал, что надо указать что это только часть от полной даты что записано в поле created_at.

Однако не понял почему MySQL может не так понять мой запрос. Ведь я явно указываю что дата такая-то.
6. Мелкий - 06 Января, 2016 - 17:26:22 - перейти к сообщению
Ну а mysql считает, что если вы хотите сравнить timestamp со строкой, значит последнюю надо приводить к timestamp.
7. lawer85 - 06 Января, 2016 - 17:30:01 - перейти к сообщению
Я имел ввиду если писать так

SELECT id FROM activities WHERE DATE_FORMAT(created_at, '%Y-%m-%d')='2016-01-03'
8. Мелкий - 06 Января, 2016 - 17:38:33 - перейти к сообщению
А так работать будет. Только медленно.
9. lawer85 - 06 Января, 2016 - 17:40:16 - перейти к сообщению
Я тему индексов плохо знаю. Вообще в чем прикол этих индексов. MySQL делает запрос и выборку, делает соответствующие записи в отдельную таблицу так и затем уже перебирает по ней, а не по всей бд я правильно понимаю?
(Добавление)
Да и для чего указывать interval 1 day ?
10. re_nat - 06 Января, 2016 - 17:52:14 - перейти к сообщению
lawer85, индексы нужны для ускорения поиска. Mysql формируем специальные деревья (читай графы) на основании заданных индексов и при поиске перебирает не все записи таблицы по порядку, а двигается по узлам дерева отталкиваясь от искомых значений.
Не заморачивайте пока себе голову оптимизацией. Всему своё время.
11. lawer85 - 06 Января, 2016 - 18:00:33 - перейти к сообщению
Спасибо. Просто раз уж разговор зашел, то надо разобраться. Мне хочется не просто знать что-то, а еще и разбираться в этом хорошо.
12. Мелкий - 06 Января, 2016 - 18:43:48 - перейти к сообщению
Просто сгенерируйте и запишите в табличку немножко данных. Записей этак тысяч сто.
Сразу станет понятно, зачем нужны индексы.

lawer85 пишет:
Да и для чего указывать interval 1 day ?

Чтобы дату конца периода посчитала СУБД. Так может быть удобнее, чем генерировать правильную дату на приложении.
13. lawer85 - 06 Января, 2016 - 18:58:18 - перейти к сообщению
created_at >= '2016-01-03' AND created_at < '2016-01-03' это условие разве не показывает MySQL что нас не интересует то, что идет не 3 января ? Уж простите, может глупые вопросы задаю.
14. Мелкий - 06 Января, 2016 - 19:23:34 - перейти к сообщению
Это условие будет ложно уже на этапе разбора запроса. Такое значение невозможно.

Или created_at >= '2016-01-03' AND created_at < '2016-01-04' и считаем дату на приложении
Или created_at >= '2016-01-03' AND created_at < '2016-01-03' + interval 1 day и дату считает SQL, потому что '2016-01-03' + interval 1 day как раз и будет '2016-01-04'

 

Powered by ExBB FM 1.0 RC1