2012-06-21 4 views
8

Załóżmy, że mam dwie tabele tak:MySQL Dołącz/Porównanie na kolumnie DATETIME (<5.6.4 and > 5.6.4)

Events 
ID (PK int autoInc), Time (datetime), Caption (varchar) 

Position 
ID (PK int autoinc), Time (datetime), Easting (float), Northing (float) 

Czy jest bezpiecznie, na przykład listę wszystkich zdarzeń i ich położenie, czy jestem przy użyciu pola Time jako moich kryteriów łączenia? Tj .:

SELECT E.*,P.* FROM Events E JOIN Position P ON E.Time = P.Time 

OR, nawet po prostu porównując wartości datetime (biorąc pod uwagę, że wartość parametryzowane mogą zawierać ułamkową część sekundy - co MySQL zawsze akceptowane), na przykład

SELECT E.* FROM Events E WHERE E.Time = @Time 

Rozumiem MySQL (przed wersją 5.6.4) wyłącznie magazynuje datetime pola BEZ milisekund. Zakładam więc, że to zapytanie będzie działać poprawnie. Jednak od wersji 5.6.4 czytałem, że MySQL może teraz przechowywać milisekundy w polu datetime.

Zakładając, że wartości datetime są wstawiane za pomocą funkcji, takich jak NOW(), milisekundy są obcięte (< 5.6.4), co mógłbym założyć, aby powyższe zapytanie zadziałało. Jednak w wersji 5.6.4 i nowszych może to NIE działać. Jestem i zawsze będę zainteresowany drugą dokładnością.

Jeśli ktoś mógłby odpowiedzieć na następujące pytania będą bardzo mile widziane:

  1. w ogólności, w jaki sposób MySQL porównać pola datetime przed sobą (pod powyższe zapytanie).
  2. Czy powyższe zapytanie jest prawidłowe i czy korzysta z indeksów w polach o czasie ? (MySQL < 5.6.4)
  3. Czy istnieje sposób na wyłączenie milisekund? To znaczy. podczas wstawiania i w warunkowych sprzężeniach/wybiera itp.? (MySQL> 5.6.4)
  4. Czy powyższe zapytanie o łączenie działa? (MySQL> 5.6.4)

EDIT

Wiem, że może rzucić się datetimes, dzięki za te, które odpowiedziało, ale próbuję zmierzyć się z korzenia problem tutaj (fakt, że typ/definicja pamięci został zmieniony) i NIE chcę używać funkcji w moich zapytaniach. To neguje całą moją pracę polegającą na optymalizowaniu zapytań z zastosowaniem indeksów itp., Nie wspominając o konieczności przepisywania wszystkich moich zapytań.

EDIT2

Może ktoś tam sugerują powodu, aby nie dołączyć na DATETIME dziedzinie z wykorzystaniem drugiego dokładność?

+0

dobrze wykorzystać swoją trzecia kwestia to data (time_column) to załatwi –

+1

wierzę 'NOW()' w 5.6.4 lub nowszy nie będzie czynnikiem w milisekundach chyba zdać w parametrze (0-6) wskazującym "* precyzja sekund ułamkowych *", więc powinieneś być w porządku dla łączenia tak długo, jak długo nie przekazujesz parametrów do 'TERAZ()' Więcej [tutaj] (http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_now) –

+0

jaka strefa czasowa jest używana dla DATETIME, dawka, której strefa czasowa ma "skoki", jak http: // stackoverflow .com/questions/6841333/why-is-odejmowanie-ten-dwa-w-1927-dając-dziwny-wynik –

Odpowiedz

4

Wydaje się, że twórcy MySQL nie chciał złamać kompatybilności wstecznej, tak aby wykorzystać milisekund, to jawnie trzeba zmienić tabele, SQL, itd., Aby korzystać z tej funkcji:

http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_now

NOW ([FSP])

w MySQL 5.6.4, jeżeli argument FSP przedstawiono na podanie precyzja sekund ułamkowych od 0 do 6, zwracana wartość zawiera część ułamkową z wielu cyfr. Przed 5.6.4 każdy argument jest ignorowany.

http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html

MySQL 5.6.4 i się rozszerza ułamki sekund obsługę czasie DateTime i wartości znacznika czasu, maksymalnie do mikrosekund (6 cyfr) precyzyjnych:

Aby zdefiniować kolumna zawierająca ułamkową część sekundową, użyj składni nazwa_typu (fsp), gdzie nazwa_typu to TIME, DATETIME lub TIMESTAMP, a fsp to precyzja ułamków sekund. Na przykład:

CREATE TABLE t1 (t TIME(3), dt DATETIME(6)); The fsp value, if given, must be in the range 0 to 6. A value of 0 signifies that there is no fractional part. If omitted, the default precision is 0. (This differs from the standard SQL default of 6, for compatibility with previous MySQL versions.) 
+0

+1 dzięki biziclop. To dobra wiadomość, nie powinienem niczego zmieniać. – Simon

+0

Właśnie uzupełniłem komentarz Zane Bien :) – biziclop

1

Wypróbuj to zapytanie. W przypadku pytania 3 i 4 będzie to działać poprawnie.Nadal nie jest to dobra praktyka, aby użyć pola czasu dla dołącza

SELECT E.*,P.* FROM Events E JOIN Position P ON date(E.Time) = date(P.Time) 

Chociaż dałem wam rozwiązanie, ale będzie ograniczony do wstawienia tym samym czasie w różnych tabelach. Wtedy będziesz mógł porównać, ale jest to dość trudne, ponieważ w tym samym czasie nie możesz uruchomić dwóch zapytań o wstawianie. Musisz więc wykonać kilka czynności w tym menu. Jeśli chcesz przeczytać więcej, przeczytaj ten artykuł.

http://billauer.co.il/blog/2009/03/mysql-datetime-epoch-unix-time/

+0

Czy mógłbyś wyjaśnić DLACZEGO to nie jest dobra praktyka, aby użyć pola czasu do łączenia. Dzięki – Simon

+0

widziałem ten wpis na blogu i podczas gdy zachęca on do dyskusji na temat używania 'DATETIME' lub' INT' jako pamięci czasu, tak naprawdę nie rozwiązuje problemów z dokładnością przy porównywaniu wartości 'DATETIME'. Używając 'JOIN' lub prostego porównania równości. – Simon

+0

Prosty przykład, w którym łączenie w kolumnie 'DATETIME' może się nie udać: ponieważ obie inserty nie mogą się zdarzyć w tym samym czasie, może wystąpić (małe) opóźnienie między nimi. Załóżmy, że pierwsza wstawka ma 19: 59: 59.999 (proszę zauważyć milisekundy), która może być obcięta do 19:59:59, a druga wstawka to tylko 1 ms później o 20: 00: 00.000, która obcina do 20:00 : 00. Powodzenia z dołączeniem. Jest to przy założeniu, że faktycznie używasz 'NOW()' w kwerendach wstawiania, a nie niektóre wstępnie obliczone wartości czasu równe dla obu zapytań. – Bart

Powiązane problemy