2011-11-18 22 views
50

Używam programu sqlite do wybierania danych między dwoma zakresami dla raportu sprzedaży. Aby wybrać dane z dwóch dat, używam następującego oświadczenia:SQL Wybierz między datami

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

To oświadczenie obejmuje wszystkie daty, nawet te, które nie spełniają kryteriów. Wprowadzony format daty jest w tym samym formacie, który otrzymuję. Nie jestem pewien, co jest nie tak, ale doceniam każdą pomoc, jaką mogę znaleźć. Dzięki!

+1

Wystarczy szybkie związane wskazówka. Jeśli zawsze możesz użyć rrrr/MM/dd jako formatu. To zatrzyma nieznośne problemy z różnicami regionalnymi, które mogą być twoim problemem. – Haedrian

Odpowiedz

69

SQLLite wymaga daty w formacie YYYY-MM-DD. Ponieważ dane w bazie danych i ciąg w zapytaniu nie są w tym formacie, prawdopodobnie traktują twoje "daty" jako ciągi.

+0

Po zmianie formatu daty ponownie uruchomiłem zapytanie jako "WYBIERZ datę z testu GDZIE MIĘDZY" 2011-11-1 "I" 2011-11-2 "; i wróciłem do wyników 2011-11-16:/ – Zombian

+26

To jest 10 i 20 dnia miesiąca. Spróbuj "MIĘDZY" 2011-11-01 "ORAZ" 2011-11-02 ". –

+0

@LarryLustig couuld powiedz mi, jak naprawić mój, Mam ten sam problem z serwerem sql 2014 –

25

Zmień dane na te formaty, aby użyć sqlite datetime formats.

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

Właściwy pomysł, ale biorąc pod uwagę, że dane wracają jest również w formacie "MM/DD/YYYY", podejrzewam, że to nadal nie zadziała, ponieważ dane w jego bazie danych będą traktowane jako ciągi, a nie daty. –

+0

@EricPetroelje Tak - ale gdy dopasujesz format w DB do formatu w zapytaniu, to by działało.Wygląda na to, że została później zmodyfikowana, aby uwzględnić zaktualizowane zapytanie po zaktualizowaniu bazy danych - chociaż zapytanie wymaga pojedynczych cudzysłowów zamiast podwójnych cudzysłowów. – vapcguy

9

Jeszcze jeden sposób, aby wybrać pomiędzy datami w SQLite jest użycie potężnego strftime funkcję:

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

Są równoważne zgodnie https://sqlite.org/lang_datefunc.html:

date(...) 

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

ale jeśli chcesz mieć większy wybór, masz to.

+0

Cytaty powinny być pojedynczymi cudzysłowami, ale w przeciwnym razie zapytanie powinno działać. – vapcguy

4

Lub możesz rzucić swój ciąg do formatu daty z data funkcja. Nawet data jest zapisana jako TEKST w DB. tak (najbardziej wykonalne wariant):

SELECT * FROM test WHERE date(date) 
BETWEEN date('2011-01-11') AND date('2011-8-11') 
+0

Myślę, że problem z tym rozwiązaniem polega na tym, że nie wskazano formatu daty TEKSTU (np. Jeśli ciąg daty jest zapisany jako "MM/DD/RRRR"). Próbowałem tego podejścia i to nie działa dla mnie, i myślę, że to jest powód. –

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

Zauważ, że mogę korzystać z formatu: dd/mm/yyyy

Jeśli używasz D/M/rrrr, zmiany substr()

nadzieję, że ten pomoże Ci.

+0

Wielkie wykorzystanie łączenia! Zagłosowałem w górę. Zauważ, że nie musisz używać 'julianday()' i używając tego, zakładasz, że twoja data jest w UTC, ponieważ 'julianday()' oblicza się w oparciu o czas GMT, więc możesz skończyć z włączeniem dat, które wpuściłeś nie chcesz, a także daty, które robisz, jeśli daty są podane w czasie lokalnym. Powinieneś być w stanie wybrać 'SELECT * FROM TableName WHERE substr (data, 7) || '-' || substr (data, 4,2) || '-' || substr (data, 1,2) MIĘDZY "2011-01-11" ORAZ "2011-08-11" i powinno działać. – vapcguy

+0

Specjalne podziękowania dla [Jeff] (http://stackoverflow.com/users/781965/jeff) i [vapcguy] (http://stackoverflow.com/users/1181535/vapcguy) Twoja interaktywność jest naprawdę zachęcająca. –

1

Specjalne podziękowania dla Jeff i vapcguy Twoja interaktywność jest naprawdę zachęcająca.

Oto bardziej złożone oświadczenie, że jest przydatna, gdy długość między „/” jest nieznany ::

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

Dzięki za komplement i musisz ci go przekazać za umiejętność wykonywania podciągów. Mimo to mam nadal tę samą uwagę na temat 'julianday()' z drugiego postu. Jest to w zasadzie ta sama odpowiedź, co druga, z wyjątkiem umieszczania logiki warunkowej w celu dodania zer wiodących dla jednocyfrowych dni i miesięcy. Prawdopodobnie należało dodać do drugiej odpowiedzi lub zastąpić ją tą edycją. Wycofano, ponieważ jest bardziej poprawny. – vapcguy

Powiązane problemy