Mysql
 sql >> база данни >  >> RDS >> Mysql

Защо MYSQL DB връща повредена стойност при осредняване върху Django models.DateTimeField?

В1:Защо базата данни не връща валидна стойност за средната стойност на тези две дати?

А: Върнатата стойност се очаква, това е добре дефинирано поведение на MySQL.

Справочно ръководство за MySQL:https://dev .mysql.com/doc/refman/5.5/en/date-and-time-types.html

В MySQL, AVG агрегатната функция работи с числови стойности.

В MySQL, DATE или DATETIME изразът може да бъде оценен числово контекст.

Като проста демонстрация, извършване на числово операция за добавяне на DATETIME имплицитно преобразува стойността дата и час в число. Тази заявка:

  SELECT NOW(), NOW()+0

връща резултат като:

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

Обърнете внимание, че стойността, върната за израза NOW()+0 е не a DATETIME , това е число .

Когато посочите SUM() или AVG() функция на DATETIME израз, което е еквивалентно на преобразуване на DATETIME в число и след това сумиране или осредняване на числото.

Тоест връщането от този израз AVG(mydatetimecol) е еквивалентен на връщането от този израз:AVG(mydatetimecol+0)

Това, което се "осреднява", е числова стойност. И вие сте забелязали, върнатата стойност не е валидна дата и час; и дори в случаите, когато изглежда като валидна дата и час, вероятно не е стойност, която бихте сметнали за истинска „средна стойност“.

В2:Как мога да получа действителната средна стойност на това поле, ако описаният начин е неуспешен?

A2: Един от начините да направите това е да преобразувате датата и часа в числова стойност, която може да бъде „точно“ осреднена, и след това да я преобразувате обратно в дата и час.

Например, можете да преобразувате датата и часа в числова стойност, представляваща брой секунди от някакъв фиксиран момент във времето, напр.

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

След това можете да „осредните“ тези стойности, за да получите среден брой секунди от фиксиран момент във времето. (ЗАБЕЛЕЖКА:внимавайте да добавяте изключително голям брой редове с изключително големи стойности и надвишаване на ограничението (максимална числова стойност), проблеми с препълването на числа.)

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

За да го преобразувате обратно в дата и час, добавете тази стойност като брой секунди обратно към фиксирания момент във времето:

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

(Обърнете внимание, че DATEIME стойностите се оценяват в часовата зона на сесията на MySQL; така че има крайни случаи, когато настройката на time_zone променлива в сесията на MySQL ще има известно влияние върху върнатата стойност.)

MySQL също така предоставя UNIX_TIMESTAMP() функция, която връща цяло число в unix стил, брой секунди от началото на ерата (полунощ на 1 януари 1970 г. UTC). Можете да го използвате, за да извършите същата операция по-сбито:

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

Обърнете внимание, че този окончателен израз наистина прави същото... преобразуване на стойността за дата и време в брой секунди от '1970-01-01 00:00:00' UTC, вземане на средно число от това и след това добавяне на тази средна стойност брой секунди обратно към '1970-01-01' UTC и накрая преобразуване обратно в DATETIME стойност, представена в текущата сесия time_zone .

В3:Django DateTimeField не е ли настроен да извършва усредняване на манипулаторите?

А: Очевидно авторите на Django са доволни от стойността, върната от базата данни за 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. SQL подреждане по брой

  2. актуализирайте таблицата с помощта на динамично подготвени изрази

  3. изпълнение на препоръките за продукти на (бедния човек).

  4. Как да сравним два резултата от заявка за равенство в MySQL?

  5. Грешка в незаконен микс от съпоставяне в MySql