Если я запускаю запрос с between
предложением, он, кажется, исключает конечное значение.
Например:
select * from person where dob between '2011-01-01' and '2011-01-31'
Это дает все результаты с dob
'2011-01-01' до '2011-01-30'; пропуск записей, где dob
стоит '2011-01-31'. Может ли кто-нибудь объяснить, почему этот запрос ведет себя таким образом, и как я могу изменить его, чтобы включить записи, где dob
'2011-01-31'? (без добавления 1 к дате окончания, потому что она была выбрана пользователями.)
BETWEEN
Включает оба значения. У меняMySQL Server 5.7
Windows 10.Ответы:
Поле,
dob
вероятно, имеет временную составляющую.Чтобы обрезать его:
select * from person where CAST(dob AS DATE) between '2011-01-01' and '2011-01-31'
источник
CAST(dob AS DATE)
можно использовать более лаконичныйDATE(dob)
.>=
и<
вместоbetween
.dob BETWEEN '2011-01-01 00:00:00' AND '2011-01-31 23:59:59
. Это связано с тем,DATE(dob)
что необходимо вычислять значение для каждой строки и нельзя использовать какие-либо индексы в этом поле.t > 23:59:59 and t < 24:00:00
. ЗачемBETWEEN
вообще иметь дело с плохо определенным ? Скорее следовать советам и использовать Давида:WHERE dob >= '2011-01-01' AND dob < '2011-02-01'
. Лучшая производительность, и она работает каждый раз.Из руководства по MySQL :
источник
Проблема в том, что 31.01.2011 на самом деле это 00:00:00 2011-01-31. Это начало дня. Днем все не входит.
источник
select * from person where dob between '2011-01-01 00:00:00' and '2011-01-31 23:59:59'
источник
2011-01-31 23:59:59
но будет включать даты до2011-01-31 23:59:58
последней секунды дня, не включенные. Это может быть незначительно, но кому-то это будет полезно.23:59:59
в себя результат. Так что оба пути включены.dob
столбец представляет собой метку времени с точностью до секунды, тоBETWEEN
события в течение последней секунды дня по-прежнему не будут пропускаться, если вместо этого не будет использоваться «2011-02-01 00:00:00»?2011-01-31 23:59:59.003
. Использование @nitrogen2011-02-01 000:00:00
будет неправильно включать нулевое время 1 февраля .... Вот почему>=
и<
следует использовать его.Является ли поле, на которое вы ссылаетесь в своем запросе, типом даты или типом DateTime ?
Типичная причина описываемого вами поведения - это использование типа DateTime, тогда как вам действительно следует использовать тип Date. То есть, если вам действительно не нужно знать, в какое время кто-то родился, просто используйте тип Date.
Причина, по которой последний день не включается в ваши результаты, заключается в том, что запрос принимает временную часть дат, которую вы не указали в своем запросе.
То есть: ваш запрос интерпретируется как «до полуночи» между 30 января 2011 года и 31 января 2011 года, но данные могут иметь значение днем позже 31 января 2011 года.
Предложение: измените поле на тип Date, если это тип DateTime.
источник
Привет, этот запрос работает для меня,
select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'
источник
select * from person where DATE(dob) between '2011-01-01' and '2011-01-31'
Удивительно, но такие преобразования - решение многих проблем в MySQL.
источник
Установите верхнюю дату на date + 1 день, поэтому в вашем случае установите ее на 2011-02-01.
источник
BETWEEN
следует игнорировать; но>=
и<
должен быть использован вместо.Вы можете запустить запрос как:
select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'
как указывали другие, если ваши даты жестко запрограммированы.
С другой стороны, если дата находится в другой таблице, вы можете добавить день и вычесть секунду (если даты сохранены без секунды / времени), например:
select * from person JOIN some_table ... where dob between some_table.initial_date and (some_table.final_date + INTERVAL 1 DAY - INTERVAL 1 SECOND)
Избегайте выполнения приведений к
dob
полям (как в принятом ответе), потому что это может вызвать огромные проблемы с производительностью (например, невозможность использовать индекс вdob
поле, если он есть). План выполнения может измениться сusing index condition
на,using where
если вы сделаете что-то вродеDATE(dob)
илиCAST(dob AS DATE)
, поэтому будьте осторожны!источник
В MySql значения включены, поэтому, когда вы даете, попробуйте попасть между '2011-01-01' и '2011-01-31'
он будет включать с
2011-01-01 00:00:00
начала до2011-01-31 00:00:00
31 января 2011 года, так как его время должно идти с2011-01-31 00:00:00 ~ 2011-01-31 23:59:59
Для верхней границы вы можете изменить на,
2011-02-01
тогда он получит все данные до2011-01-31 23:59:59
источник