SQL Выбрать между датами

45

Я запускаю sqlite для выбора данных между двумя диапазонами для отчета о продажах. Чтобы выбрать данные из двух дат, я использую следующий оператор:

SELECT * FROM test WHERE date BETWEEN "11/1/2011" AND "11/8/2011";

Это выражение захватывает все даты, даже те, которые не соответствуют критериям. Формат даты, который вы видите, находится в том же формате, который я возвращаю. Я не уверен, что неправильно, но признаю любую помощь, которую я могу найти. Спасибо!

  • 2
    Просто быстрый совет. Если вы всегда можете использовать yyyy / MM / dd в качестве формата. Это остановит надоедливые проблемы региональных различий, которые могут быть вашей проблемой.
Теги:
sqlite3

6 ответов

63
Лучший ответ

SQLLite требует, чтобы даты находились в формате YYYY-MM-DD. Поскольку данные в вашей базе данных и строка в вашем запросе не указаны в этом формате, возможно, это относится к вашим "датам" в виде строк.

  • 1
    После изменения формата даты я снова запустил запрос как «ВЫБЕРИТЕ дату ИЗ ТЕСТА, ГДЕ ДАТА МЕЖДУ« 2011-11-1 »И« 2011-11-2 »; ' и вернули результаты за 2011-11-16: /
  • 28
    Это 10 и 20 числа месяца. Попробуйте BETWEEN '2011-11-01' AND '2011-11-02' .
Показать ещё 2 комментария
25

Измените свои данные на эти форматы, чтобы использовать форматы sqlite datetime.

YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD

SELECT * FROM test WHERE date BETWEEN '2011-01-11' AND '2011-08-11'
  • 0
    Правильная идея, но, учитывая, что возвращаемые данные также имеют формат MM/DD/YYYY , я подозреваю, что это все равно не сработает, поскольку данные в его базе данных будут обрабатываться как строки, а не как даты.
  • 0
    @EricPetroelje Да - но как только вы сопоставите формат в БД с форматом в запросе, он будет работать. Похоже, что это было отредактировано позже, чтобы включить то, каким должен быть обновленный запрос после обновления БД, хотя для запроса нужны одинарные кавычки, а не двойные.
9

Еще один способ выбора между датами в SQLite - использовать мощную функцию strftime:

SELECT * FROM test WHERE strftime('%Y-%m-%d', date) BETWEEN "11-01-2011" AND "11-08-2011"

Они эквивалентны в соответствии с https://sqlite.org/lang_datefunc.html:

date(...)

strftime('%Y-%m-%d', ...)

но если вы хотите больше выбора, у вас есть.

  • 0
    Кавычки должны быть одинарными, но в противном случае запрос должен работать.
5

Или вы можете передать свою строку в формат даты с помощью функции date. Даже дата хранится как ТЕКСТ в БД. Подобно этому (наиболее работоспособный вариант):

SELECT * FROM test WHERE date(date) 
BETWEEN date('2011-01-11') AND date('2011-8-11')
  • 0
    Я думаю, что проблема с этим решением состоит в том, что вы не указываете формат даты ТЕКСТА (например, если строка даты хранится как «ММ / ДД / ГГГГ»). Я попробовал этот подход, и он не работает для меня, и я думаю, что в этом причина.
1

Особая благодарность Jeff и vapcguy ваша интерактивность действительно обнадеживает.

Вот более сложный оператор, который полезен, когда длина между '/' неизвестна::

SELECT * FROM tableName
WHERE julianday(
    substr(substr(date, instr(date, '/')+1), instr(substr(date, instr(date, '/')+1), '/')+1)
||'-'||
    case when length(
    substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1),'/')-1)
    )=2
    then
    substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1)
    else
    '0'||substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1)
    end
||'-'||
    case when length(substr(date,1, instr(date, '/')-1 )) =2
    then substr(date,1, instr(date, '/')-1 )
    else
    '0'||substr(date,1, instr(date, '/')-1 )
    end
) BETWEEN julianday('2015-03-14') AND julianday('2015-03-16') 
  • 0
    Спасибо за комплимент, и я должен передать его вам за вашу способность делать подстроки. Мой же комментарий о julianday() из другого поста все еще применяется, хотя. Это в основном тот же ответ, что и другой, за исключением того, что вы добавили условную логику, чтобы добавить начальные нули для однозначных дней и месяцев. Вероятно, следовало добавить к другому ответу или заменить его этим редактированием. Принято, поскольку это более правильно, хотя.
1
SELECT *
FROM TableName
WHERE julianday(substr(date,7)||'-'||substr(date,4,2)||'-'||substr(date,1,2)) BETWEEN julianday('2011-01-11') AND julianday('2011-08-11')

Обратите внимание, что я использую формат: dd/mm/yyyy

Если вы используете d/m/yyyy, измените substr()

Надеюсь, это поможет вам.

  • 0
    Отличное использование сращивания! Проголосовал. Обратите внимание, что вам не нужно использовать julianday() , однако, и при использовании этого предполагается, что ваша дата указана в UTC, потому что julianday() рассчитывается по времени по Гринвичу, так что вы можете в конечном итоге включить даты, которые вы не хотите, и включая даты, которые вы делаете, если ваши даты по местному времени. Вы должны иметь возможность просто сделать SELECT * FROM TableName WHERE substr(date,7)||'-'||substr(date,4,2)||'-'||substr(date,1,2) BETWEEN '2011-01-11' AND '2011-08-11' и это должно работать.
  • 0
    Отдельное спасибо Джеффу и vapcguy, ваша интерактивность действительно воодушевляет.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню