#mysql #datetime
#mysql #дата и время
Вопрос:
Я хочу вернуть данные, которые не находятся между текущей датой и последними 7 днями.
Мой оператор SELECT отображается нормально, но он также возвращает данные текущего дня.
SELECT
customer.id AS id,
customer.customer_id AS customer_id,
customer.name AS name,
customer.phone1 AS phone1,
customer.location_area AS location_area,
sales.post_date AS post_date
FROM
sales
INNER JOIN
customer
ON
sales.customer_id = customer.customer_id
WHERE
post_date
NOT BETWEEN
CAST( DATE_SUB(NOW(), INTERVAL 7 DAY) AS DATE )
AND
CAST( NOW() AS DATE )
ORDER BY
sales.id
DESC
LIMIT 30
Пожалуйста, обратите внимание, что поле customer_id, используемое в предложении ON, не является первичным ключом ни в одной из двух таблиц, на которые ссылаются.
Чего может не хватать в моем запросе?
Комментарии:
1. очевидный, но необходимый вопрос — является ли «post_date» полем даты и времени (а не varchar или чем-то еще)? Если нет, вам может потребоваться привести его перед выполнением сравнения
2. @ADyson, поле ‘post_date’ — это поле даты и времени
Ответ №1:
Обычно эта проблема связана с путаницей в отношении различных значений DATE
типов данных, с одной стороны, и TIMESTAMP
/ или DATETIME
типов данных, с другой.
Допустим NOW()
, есть 1-April-2017 09:35
. И, допустим, у вас есть строка в вашей sales
таблице со post_date
значением 1-April-2017 08:20
. Допустим, ваш post_date
столбец имеет тип данных DATETIME
.
Тогда ваше предложение WHERE выглядит следующим образом после применения значений.
WHERE '2017-04-01 08:20' NOT BETWEEN CAST( '2017-03-25 09:35' AS DATE )
AND CAST( '2017-04-01 09:35' AS DATE )
Применяя CAST
операции, мы получаем.
WHERE '2017-04-01 08:20' NOT BETWEEN '2017-03-25'
AND '2017-04-01'
Наконец, при сравнении DATETIME
или TIMESTAMP
со DATE
значением DATE
значение интерпретируется как имеющее время полуночи. Итак, ваш запрос выглядит следующим образом:
WHERE '2017-04-01 08:20' NOT BETWEEN '2017-03-25 00:00:00'
AND '2017-04-01 00:00:00'
И, угадайте, что? '2017-04-01 08:20'
после '2017-04-01 00:00:00'
.
Что вам нужно, так это:
WHERE
NOT (
post_date >= CURDATE() - INTERVAL 7 DAY --on or after midnight 2016-3-25
AND post_date < CURDATE() INTERVAL 1 DAY --before midnight 2016-04-02
)
Пожалуйста, обратите внимание, что это выражение охватывает всего восемь дней.
Вы не можете использовать BETWEEN
для такого сравнения, потому что вам нужен <
конец диапазона, и BETWEEN
использует <=
для концов всех его диапазонов.
Кроме того, CURDATE()
его гораздо легче читать, чем CAST(NOW() AS DATE)
.