Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Dlaczego MYSQL DB zwraca uszkodzoną wartość podczas uśredniania modeli Django.DateTimeField?

P1:Dlaczego baza danych nie zwraca prawidłowej wartości średniej z tych dwóch dat?

O: Zwrócona wartość jest oczekiwana, jest to dobrze zdefiniowane zachowanie MySQL.

Podręcznik MySQL Reference:https://dev .mysql.com/doc/refman/5.5/en/daty-i-godziny.html

W MySQL AVG funkcja agregująca działa na liczbie wartości.

W MySQL DATE lub DATETIME wyrażenie może być ocenione jako liczba kontekst.

W ramach prostej demonstracji wykonanie numerycznego operacja dodawania na DATETIME niejawnie konwertuje wartość daty i godziny na liczbę. To zapytanie:

  SELECT NOW(), NOW()+0

zwraca wynik taki jak:

  NOW()                                NOW()+0  
  -------------------  -----------------------
  2015-06-23 17:57:48    20150623175748.000000

Zwróć uwagę, że wartość zwracana dla wyrażenia NOW()+0 jest nie a DATETIME , to liczba .

Kiedy określisz SUM() lub AVG() funkcja na DATETIME wyrażenie, które jest równoważne konwersji DATETIME na liczbę, a następnie zsumowanie lub uśrednienie liczby.

Oznacza to, że zwrot z tego wyrażenia AVG(mydatetimecol) jest odpowiednikiem zwrotu z tego wyrażenia:AVG(mydatetimecol+0)

To, co jest „uśredniane”, jest wartością liczbową. Zauważyłeś, że zwrócona wartość nie jest prawidłową datą i godziną; a nawet w przypadkach, gdy wygląda to na prawidłową datę i godzinę, prawdopodobnie nie jest to wartość, którą uważasz za prawdziwą „średnią”.

P2:Jak uzyskać rzeczywistą średnią tego pola, jeśli opisany sposób nie powiedzie się?

A2: Jednym ze sposobów, aby to zrobić, jest przekonwertowanie daty i godziny na wartość liczbową, którą można „dokładnie” uśrednić, a następnie przekonwertować ją z powrotem na datę i godzinę.

Na przykład możesz przekonwertować datę i godzinę na wartość liczbową reprezentującą liczbę sekund od pewnego ustalonego punktu w czasie, np.

  TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)

Następnie możesz „uśrednić” te wartości, aby uzyskać średnią liczbę sekund od ustalonego punktu w czasie. (UWAGA:uważaj na sumowanie bardzo dużej liczby wierszy, z bardzo dużymi wartościami i przekraczaniem limitu (maksymalna wartość liczbowa), problemy z przepełnieniem liczbowym.)

  AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date))

Aby przekonwertować to z powrotem na datę i godzinę, dodaj tę wartość jako liczbę sekund powrót do ustalonego punktu w czasie:

  '2015-01-01' + INTERVAL AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)) SECOND

(Zauważ, że DATEIME wartości są oceniane w strefie czasowej sesji MySQL; więc istnieją skrajne przypadki, w których ustawienie time_zone zmienna w sesji MySQL będzie miała pewien wpływ na zwracaną wartość.)

MySQL udostępnia również funkcję UNIX_TIMESTAMP() funkcja zwracająca uniksową wartość całkowitą, liczbę sekund od początku ery (północ 1 stycznia 1970 UTC). Możesz użyć tego, aby wykonać tę samą operację w bardziej zwięzły sposób:

  FROM_UNIXTIME(AVG(UNIX_TIMESTAMP(t.my_date)))

Zauważ, że to końcowe wyrażenie naprawdę robi to samo… konwertuje wartość daty i godziny na liczbę sekund od czasu UTC „1970-01-01 00:00:00”, biorąc średnią liczbową z tego, a następnie dodając tę ​​średnią liczba sekund z powrotem do „1970-01-01” UTC i ostatecznie przekonwertowanie tego z powrotem na DATETIME wartość reprezentowana w bieżącej sesji time_zone .

P3:Czy Django DateTimeField nie jest skonfigurowany do obsługi uśredniania?

O: Najwyraźniej autorzy Django są zadowoleni z wartości zwracanej z bazy danych dla wyrażenia SQL AVG(datetime) .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Xampp nie uruchomi serwera MySQL na Mac OSX?

  2. Pamięć tablicy bajtów Mysql

  3. Używanie PHP DOM do tworzenia plików XML z danych MySQL

  4. wiele do wielu relacji

  5. Utworzyć tabelę w MySQL, która pasuje do innej tabeli?