WHERE
klauzula jest niewłaściwie umieszczona, musi podążać za odwołaniami do tabeli i operacjami JOIN.
Coś takiego:
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
EDYTUJ (trzy lata później)
Powyższe zasadniczo odpowiada na pytanie „Próbowałem dodać klauzulę WHERE do mojego zapytania, a teraz zapytanie zwraca błąd, jak to naprawić?”
Co do pytania o napisanie warunku sprawdzającego zakres dat „ostatnie 7 dni”...
To naprawdę zależy od interpretacji specyfikacji, typu danych kolumny w tabeli (DATE lub DATETIME) i jakie dane są dostępne... co powinno zostać zwrócone.
Podsumowując:ogólne podejście polega na określeniu „początku” zakresu dat/dat i godzin oraz „końca” tego zakresu i odwołanie się do nich w zapytaniu. Zastanówmy się nad czymś łatwiejszym... wszystkie wiersze dla "wczoraj".
Jeśli nasza kolumna to DATE. Zanim włączymy wyrażenie do zapytania, możemy je przetestować za pomocą prostego SELECT
SELECT DATE(NOW()) + INTERVAL -1 DAY
i sprawdź, czy zwrócony wynik jest tym, czego oczekujemy. Następnie możemy użyć tego samego wyrażenia w klauzuli WHERE, porównując je z kolumną DATE w następujący sposób:
WHERE datecol = DATE(NOW()) + INTERVAL -1 DAY
Dla kolumny DATETIME lub TIMESTAMP możemy użyć >=
i <
porównania nierówności w celu określenia zakresu
WHERE datetimecol >= DATE(NOW()) + INTERVAL -1 DAY
AND datetimecol < DATE(NOW()) + INTERVAL 0 DAY
W przypadku „ostatnich 7 dni” musimy wiedzieć, czy to oznacza od tego momentu, wstecz 7 dni… np. ostatnie 7*24 godziny , w tym składnik czasu w porównaniu, ...
WHERE datetimecol >= NOW() + INTERVAL -7 DAY
AND datetimecol < NOW() + INTERVAL 0 DAY
ostatnie siedem pełnych dni, nie licząc dzisiejszego
WHERE datetimecol >= DATE(NOW()) + INTERVAL -7 DAY
AND datetimecol < DATE(NOW()) + INTERVAL 0 DAY
lub ostatnich sześciu pełnych dni plus do tej pory dzisiaj...
WHERE datetimecol >= DATE(NOW()) + INTERVAL -6 DAY
AND datetimecol < NOW() + INTERVAL 0 DAY
Polecam testowanie wyrażeń po prawej stronie w instrukcji SELECT, możemy użyć zmiennej zdefiniowanej przez użytkownika zamiast NOW() do testowania, nie będąc przywiązanym do tego, co zwraca NOW(), abyśmy mogli testować granice w ciągu tygodnia/miesiąca granice /rok i tak dalej.
SET @clock = '2017-11-17 11:47:47' ;
SELECT DATE(@clock)
, DATE(@clock) + INTERVAL -7 DAY
, @clock + INTERVAL -6 DAY
Gdy mamy wyrażenia, które zwracają wartości, które działają dla „początku” i „końca” w naszym konkretnym przypadku użycia, co rozumiemy przez „ostatnie 7 dni”, możemy użyć tych wyrażeń w porównaniach zakresów w klauzuli WHERE.
(Niektórzy programiści wolą używać DATE_ADD
i DATE_SUB
funkcje w miejsce + INTERVAL val DAY/HOUR/MINUTE/MONTH/YEAR
składnia.
MySQL zapewnia kilka wygodnych funkcji do pracy z typami danych DATE, DATETIME i TIMESTAMP... DATE, LAST_DAY,
Niektórzy programiści wolą obliczać początek i koniec w innym kodzie i dostarczać literały łańcuchowe w zapytaniu SQL, tak aby zapytanie przesłane do bazy danych było
WHERE datetimecol >= '2017-11-10 00:00'
AND datetimecol < '2017-11-17 00:00'
I to podejście też działa. (Moim preferencją byłoby jawne rzutowanie tych literałów na DATETIME, albo za pomocą CAST, CONVERT lub po prostu sztuczką + INTERVAL...
WHERE datetimecol >= '2017-11-10 00:00' + INTERVAL 0 SECOND
AND datetimecol < '2017-11-17 00:00' + INTERVAL 0 SECOND
Wszystko to zakłada, że przechowujemy „daty” w odpowiednich typach danych DATE, DATETIME i/lub TIMESTAMP, a nie przechowujemy ich jako ciągi w różnych formatach, np. 'dd/mm/yyyy'
, m/d/yyyy
, daty juliańskie lub w sporadycznie niekanonicznych formatach lub jako liczba sekund od początku epoki, ta odpowiedź musiałaby być znacznie dłuższa.