web-dev-qa-db-fra.com

MySQL Select 7 derniers jours

J'ai lu quelques articles ici et ne semble rien de spécial, mais je ne peux toujours pas sélectionner les entrées des derniers jours.

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);

Si j'ajoute entre aujourd'hui et les 7 derniers jours, mon code ne produira rien.

26
karadayi

La clause WHERE est mal placée, elle doit suivre les références du tableau et les opérations JOIN.

Quelque chose comme ça:

 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

MODIFIER (trois ans et plus plus tard)

Ce qui précède répond essentiellement à la question "J'ai essayé d'ajouter une clause WHERE à ma requête et maintenant la requête renvoie une erreur, comment puis-je la corriger?"

Quant à une question sur l'écriture d'une condition qui vérifie une plage de dates de "7 derniers jours" ...

Cela dépend vraiment de l'interprétation de la spécification, du type de données de la colonne dans la table (DATE ou DATETIME) et des données disponibles ... de ce qui doit être retourné.

Pour résumer: l'approche générale consiste à identifier un "début" pour la plage date/datetime et une "fin" de cette plage, et à les référencer dans une requête. Considérons quelque chose de plus facile ... toutes les lignes pour "hier".

Si notre colonne est de type DATE. Avant d'incorporer une expression dans une requête, nous pouvons la tester dans un simple SELECT

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

et vérifiez que le résultat retourné est ce que nous attendons. Ensuite, nous pouvons utiliser cette même expression dans une clause WHERE, en la comparant à une colonne DATE comme celle-ci:

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

Pour une colonne DATETIME ou TIMESTAMP, nous pouvons utiliser >= et < comparaisons d'inégalité pour spécifier une plage

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

Pour les "7 derniers jours", nous devons savoir si cela signifie à partir de maintenant, revenir 7 jours ... par exemple les 7 * 24 dernières heures, y compris la composante temps dans la comparaison, ...

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

les sept derniers jours complets, sans compter aujourd'hui

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

ou six derniers jours complets et jusqu'à présent aujourd'hui ...

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

Je recommande de tester les expressions sur le côté droit dans une instruction SELECT, nous pouvons utiliser une variable définie par l'utilisateur à la place de NOW () pour les tests, sans être lié à ce que NOW () renvoie afin que nous puissions tester les bordures, à travers la semaine/mois/limites annuelles, etc.

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

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

Une fois que nous avons des expressions qui renvoient des valeurs qui fonctionnent pour "début" et "fin" pour notre cas d'utilisation particulier, ce que nous entendons par "7 derniers jours", nous pouvons utiliser ces expressions dans les comparaisons de plages dans la clause WHERE.

(Certains développeurs préfèrent utiliser le DATE_ADD et DATE_SUB fonctions à la place de + INTERVAL val DAY/HOUR/MINUTE/MONTH/YEAR syntaxe.

Et MySQL fournit quelques fonctions pratiques pour travailler avec les types de données DATE, DATETIME et TIMESTAMP ... DATE, LAST_DAY,

Certains développeurs préfèrent calculer le début et la fin dans un autre code et fournir des littéraux de chaîne dans la requête SQL, de sorte que la requête soumise à la base de données soit

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

Et cette approche fonctionne aussi. (Ma préférence serait de convertir explicitement ces littéraux de chaîne en DATETIME, soit avec CAST, CONVERT ou simplement l'astuce + INTERVAL ...

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

Ce qui précède suppose que nous stockons des "dates" dans les types de données DATE, DATETIME et/ou TIMESTAMP appropriés, et que nous ne les stockons pas sous forme de chaînes dans divers formats, par ex. 'dd/mm/yyyy', m/d/yyyy, dates juliennes, ou dans des formats sporadiquement non canoniques, ou en nombre de secondes depuis le début de l'époque, cette réponse devrait être beaucoup plus longue.

73
spencer7593

Puisque vous utilisez un INNER JOIN, vous pouvez simplement mettre les conditions dans la clause WHERE, comme ceci:

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;
5
fthiella