MySQL Выберите последние 7 дней

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

SELECT 
    p1.kArtikel, 
    p1.cName, 
    p1.cKurzBeschreibung, 
    p1.dLetzteAktualisierung, 
    p1.dErstellt, 
    p1.cSeo,
    p2.kartikelpict,
    p2.nNr,
    p2.cPfad

FROM 
    tartikel AS p1 WHERE DATE(dErstellt) > (NOW() - INTERVAL 7 DAY)

INNER JOIN 
    tartikelpict AS p2 
    ON (p1.kArtikel = p2.kArtikel) WHERE (p2.nNr = 1)

ORDER BY 
    p1.kArtikel DESC

LIMIT
    100;', $connection);

Если я добавлю между сегодняшним и последним 7 днями, мой код ничего не выводит.

Ответ 1

Предложение WHERE неуместно, оно должно следовать за ссылками на таблицы и операциями JOIN.

Что-то вроде этого:

 FROM tartikel p1 
 JOIN tartikelpict p2 
   ON p1.kArtikel = p2.kArtikel 
  AND p2.nNr = 1
WHERE p1.dErstellt >= DATE(NOW()) - INTERVAL 7 DAY
ORDER BY p1.kArtikel DESC

EDIT (три плюс спустя)

Вышеупомянутый, по сути, отвечает на вопрос "Я попытался добавить предложение WHERE к моему запросу, и теперь запрос возвращает ошибку, как мне ее исправить?"

Что касается вопроса о написании условия, которое проверяет диапазон дат "последние 7 дней"...

Это действительно зависит от интерпретации спецификации, каков тип данных столбца в таблице (DATE или DATETIME) и какие данные доступны... что должно быть возвращено.

Подводя итог: общий подход состоит в том, чтобы идентифицировать "начало" для диапазона даты/времени и времени "конец" этого диапазона и ссылаться на те, которые содержатся в запросе. Давайте рассмотрим что-то проще... все строки для "вчера".

Если наш столбец является типом DATE. Прежде чем мы включим выражение в запрос, мы можем протестировать его в простом SELECT

 SELECT DATE(NOW()) + INTERVAL -1 DAY 

и проверьте, что возвращаемый результат - это то, что мы ожидаем. Затем мы можем использовать это же выражение в предложении WHERE, сравнивая его с столбцом DATE следующим образом:

 WHERE datecol = DATE(NOW()) + INTERVAL -1 DAY

Для столбца DATETIME или TIMESTAMP мы можем использовать сравнения неравенств >= и <, чтобы указать диапазон

 WHERE datetimecol >= DATE(NOW()) + INTERVAL -1 DAY
   AND datetimecol <  DATE(NOW()) + INTERVAL  0 DAY

В течение "последних 7 дней" нам нужно знать, означает ли это из этого момента прямо сейчас, назад 7 дней... например. последние 7 * 24 часа, включая компонент времени в сравнении,...

 WHERE datetimecol >= NOW() + INTERVAL -7 DAY
   AND datetimecol <  NOW() + INTERVAL  0 DAY

последние семь полных дней, не считая сегодня

 WHERE datetimecol >= DATE(NOW()) + INTERVAL -7 DAY
   AND datetimecol <  DATE(NOW()) + INTERVAL  0 DAY

или за последние шесть полных дней плюс до сегодняшнего дня...

 WHERE datetimecol >= DATE(NOW()) + INTERVAL -6 DAY
   AND datetimecol <  NOW()       + INTERVAL  0 DAY

Я рекомендую тестировать выражения с правой стороны в инструкции SELECT, мы можем использовать пользовательскую переменную вместо NOW() для тестирования, а не привязываться к тому, что возвращает NOW(), чтобы мы могли тестировать границы, через неделя/месяц/год и т.д.

SET @clock = '2017-11-17 11:47:47' ;

SELECT DATE(@clock)
     , DATE(@clock) + INTERVAL -7 DAY 
     , @clock + INTERVAL -6 DAY 

Как только у нас появятся выражения, которые возвращают значения, которые работают для "start" и "end" для нашего конкретного случая использования, что мы подразумеваем под "последние 7 дней", мы можем использовать эти выражения в сравнении диапазонов в предложении WHERE.

(Некоторые разработчики предпочитают использовать DATE_ADD и DATE_SUB вместо синтаксиса + INTERVAL val DAY/HOUR/MINUTE/MONTH/YEAR.

И MySQL предоставляет некоторые удобные функции для работы с типами данных DATE, DATETIME и TIMESTAMP... DATE, LAST_DAY,

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

  WHERE datetimecol >= '2017-11-10 00:00'
    AND datetimecol <  '2017-11-17 00:00'

И этот подход тоже работает. (Мое предпочтение заключалось в том, чтобы явно использовать эти строковые литералы в DATETIME, либо с CAST, CONVERT, либо просто с трюком + INTERVAL...

  WHERE datetimecol >= '2017-11-10 00:00' + INTERVAL 0 SECOND
    AND datetimecol <  '2017-11-17 00:00' + INTERVAL 0 SECOND

Выше все предполагает, что мы сохраняем "даты" в соответствующих типах данных DATE, DATETIME и/или TIMESTAMP и не сохраняем их как строки в различных форматах, например. 'dd/mm/yyyy', m/d/yyyy, юлианских дат или в спорадически неканонических форматах или в виде нескольких секунд с начала эпохи, этот ответ должен быть намного длиннее.

Ответ 2

Поскольку вы используете INNER JOIN, вы можете просто поместить условия в предложение WHERE, например:

SELECT 
    p1.kArtikel, 
    p1.cName, 
    p1.cKurzBeschreibung, 
    p1.dLetzteAktualisierung, 
    p1.dErstellt, 
    p1.cSeo,
    p2.kartikelpict,
    p2.nNr,
    p2.cPfad  
FROM 
    tartikel AS p1 INNER JOIN tartikelpict AS p2 
    ON p1.kArtikel = p2.kArtikel
WHERE
  DATE(dErstellt) > (NOW() - INTERVAL 7 DAY)
  AND p2.nNr = 1
ORDER BY 
  p1.kArtikel DESC
LIMIT
    100;