2010-10-20 21 views
28

Nie wiem, od czego zacząć. Czy ktokolwiek może mi pomóc/wskazać mi właściwy kierunek.Datownik MySQL wybierz zakres dat

Mam kolumny timestamp w MySQL i chcę, aby wybrać zakres dat, na przykład, wszystkie znaczniki czasu, które są w październiku 2010.

Dzięki.

+1

Niestety, nie wspomniano powyżej, jest to uniksowy znacznik czasu, a nie znacznik czasu mysql. – DRKM

+0

Widziałem ten post, a mój znacznik czasu działa dobrze problemu, z którym się teraz borykam, jeśli wywołanie go z łączeniem zawsze przywraca zerowe wiersze zwrócone ... moje zapytanie wygląda tak: SELECT * FROM db.t1, db.t2 GDZIE t2 .t1_id = t1.id ORAZ znacznik czasu> = "2014-06-21" ORAZ znacznik czasu <= '2014-07-20'; –

Odpowiedz

35

Zwykle byłoby to:

SELECT * 
    FROM yourtable 
WHERE yourtimetimefield>='2010-10-01' 
    AND yourtimetimefield< '2010-11-01' 

Ale ponieważ masz znaczników czasu Uniksa, trzeba coś takiego:

SELECT * 
    FROM yourtable 
WHERE yourtimetimefield>=unix_timestamp('2010-10-01') 
    AND yourtimetimefield< unix_timestamp('2010-11-01') 
+0

Dziękujemy! (5 dodatkowych znaków) – DRKM

+1

@merlinbeard To faktycznie działa zupełnie dobrze z indeksami, ponieważ obliczone wartości są statyczne i mogą być porównywane bezpośrednio z wartością 'yourtimefield'. Teraz, gdybyś miał "WHERE FROM_UNIXTIME (yourtimefield)> =" 2010-10-01'', to uniemożliwiłoby indeksowanie, ponieważ wartość dla porównania z formatem daty musiałaby zostać obliczona dla każdego wiersza. To powiedziawszy. Ciągle sugerowałbym używanie dat, datetime, datowników zamiast dat unixowych dla większości przypadków użycia. –

+0

@MikeBrant: prawidłowa obserwacja. Wyrażenie to jest obliczane jeden raz i składa się na stałą wartość, i nadal można je dopasować do indeksu na 'yourtimefield'. Natychmiast po komentarzu merlinbearda otrzymałem kilka komentarzy, pokazujących, że ludzie często głosują, nie rozumiejąc w pełni, o co głosują. Hej, brzmi jak polityka :) –

5
SELECT * FROM table WHERE col >= '2010-10-01' AND col <= '2010-10-31' 
+0

Przepraszam, powinienem był wspomnieć, że to uniksowy znacznik czasu, a nie znacznik czasu mysql (ważne informacje, których nie można przegapić!) – DRKM

+0

Widziałem ten post i mój znacznik czasu działa dobrze problemu, z którym się teraz borykam, jeśli wywołanie go z łączeniem zawsze przywraca zerowe wiersze zwrócone –

+0

Tak więc, co by się stało z rekordami, które mają znacznik czasu '2010-10-31 09: 00: 00'? –

34

Kompaktowy, elastyczne metody dla znaczników czasu bez ułamków sekund będzie:

SELECT * FROM table_name 
WHERE field_name 
BETWEEN UNIX_TIMESTAMP('2010-10-01') AND UNIX_TIMESTAMP('2010-10-31 23:59:59') 

Jeśli używasz ułamkowych sekund i najnowszej wersji MySQL, lepiej jest podejść do korzystania z operatorów >= i < zgodnie z Wouter's answer.

Oto przykład pól czasowych zdefiniowane w części sekundy precyzją (maksymalna precyzja w użyciu):

mysql> create table time_info (t_time time(6), t_datetime datetime(6), t_timestamp timestamp(6), t_short timestamp null); 
Query OK, 0 rows affected (0.02 sec) 

mysql> insert into time_info set t_time = curtime(6), t_datetime = now(6), t_short = t_datetime; 
Query OK, 1 row affected (0.01 sec) 

mysql> select * from time_info; 
+-----------------+----------------------------+----------------------------+---------------------+ 
| 22:05:34.378453 | 2016-01-11 22:05:34.378453 | 2016-01-11 22:05:34.378453 | 2016-01-11 22:05:34 | 
+-----------------+----------------------------+----------------------------+---------------------+ 
1 row in set (0.00 sec) 
+0

+1, aby uniknąć konwersji kolumny dla każdego porównania. Można mieć nadzieję, że to było całkiem wydajne! –

+0

@Jimbo: nie, 'BETWEEN' nie jest tutaj dobrą opcją, ponieważ jest nieobejmujący na obu końcach. Będziesz musiał napisać coś pomiędzy "2010-10-01 00:00:00" i "2010-10-31 23:59:59", aby uzyskać poprawne odpowiedzi i mam nadzieję, że nie użyjesz milisekund . Ponadto, 31 września nie istnieje, ponieważ wrzesień ma tylko 30 dni. Jeśli oznaczało to "30", to nie jest to poprawne, ponieważ dane z września zostaną zwrócone. W praktyce MySQL interpretuje to jako 1 października (całkiem zadbane), co byłoby poprawne tutaj. Nie jestem pewien, dlaczego napisałeś to jako 31 września. –

+0

@WoutervanNifterick nie wiem dokładnie, co się dzieje z wartościami, ale naprawione. Dodałem komentarz dotyczący fsp, ponieważ został napisany, zanim zadziałał – Cez

3

miarę możliwości unikać stosowania funkcji do kolumny w miarę punktach:

SELECT * 
    FROM table_name 
WHERE timestamp >= UNIX_TIMESTAMP('2010-10-01 00:00:00') 
    AND timestamp < UNIX_TIMESTAMP('2010-11-01 00:00:00'); 

Zastosowanie funkcji do kolumny timestamp (np. FROM_UNIXTIME (timestamp) = ...) powoduje, że indeksowanie jest znacznie trudniejsze.

3

Ta kwerenda SQL wyodrębni dane za Ciebie. Jest to łatwe i szybkie.

SELECT * 
    FROM table_name 
    WHERE extract(YEAR_MONTH from timestamp)="201010"; 
3

Widzę ludzi, którzy dają wiele komentarzy na temat tego pytania. Ale myślę, że proste użycie LIKE może być łatwiejsze do uzyskania danych z tabeli.

SELECT * FROM table WHERE COLUMN LIKE '2013-05-11%' 

Użyj LIKE i wyszukuj dane po dzikim znaku. Mam nadzieję, że rozwiąże to twój problem.

+0

Co zostało poddane edycji? – abhijitcaps

0

Jeśli masz timestamp mysql, coś jak 2013-09-29 22:27:10 można to zrobić

select * from table WHERE MONTH(FROM_UNIXTIME(UNIX_TIMESTAMP(time)))=9; 

Konwersja do systemu UNIX, a następnie użyj funkcji czas uniksowy wyodrębnić miesiąc, w tym przypadku do 9 września.