P1:¿Por qué la base de datos no devuelve un valor válido para el promedio de estas dos fechas?
Manual de referencia de MySQL:https://dev .mysql.com/doc/refman/5.5/en/date-and-time-types.html
En MySQL, el AVG
la función agregada opera en numeric valores.
En MySQL, una DATE
o DATETIME
expresión se puede evaluar en un numérico contexto.
Como demostración simple, realizando un numérico operación de adición en un DATETIME
implícitamente convierte el valor de fecha y hora en un número. Esta consulta:
SELECT NOW(), NOW()+0
devuelve un resultado como:
NOW() NOW()+0
------------------- -----------------------
2015-06-23 17:57:48 20150623175748.000000
Tenga en cuenta que el valor devuelto por la expresión NOW()+0
es no un DATETIME
, es un número .
Cuando especifica un SUM()
o AVG()
función en un DATETIME
expresión, eso es equivalente a convertir el DATETIME
en un número, y luego sumando o promediando el número.
Es decir, el retorno de esta expresión AVG(mydatetimecol)
es equivalente al retorno de esta expresión:AVG(mydatetimecol+0)
Lo que se "promedia" es un valor numérico. Y ha observado que el valor devuelto no es una fecha y hora válida; e incluso en los casos en que parece una fecha y hora válida, es probable que no sea un valor que consideraría un verdadero "promedio".
P2:¿Cómo obtengo el promedio real de este campo si falla la forma descrita?
Por ejemplo, podría convertir la fecha y hora en un valor numérico que represente una cantidad de segundos desde algún punto fijo en el tiempo, por ejemplo,
TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)
A continuación, podría "promediar" esos valores para obtener una cantidad de segundos promedio. desde un punto fijo en el tiempo. (NOTA:tenga cuidado de sumar una cantidad extremadamente grande de filas, con valores extremadamente grandes y exceder el límite (valor numérico máximo), problemas de desbordamiento numérico).
AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date))
Para volver a convertir eso en una fecha y hora, agregue ese valor como un número de segundos volver a un punto fijo en el tiempo:
'2015-01-01' + INTERVAL AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)) SECOND
(Tenga en cuenta que el DATEIME
los valores se evalúan en la zona horaria de la sesión de MySQL; por lo que hay casos extremos en los que la configuración de la time_zone
variable en la sesión de MySQL tendrá alguna influencia en el valor devuelto.)
MySQL también proporciona un UNIX_TIMESTAMP()
función que devuelve un valor entero de estilo Unix, número de segundos desde el comienzo de la era (medianoche del 1 de enero de 1970 UTC). Puede usarlo para realizar la misma operación de manera más concisa:
FROM_UNIXTIME(AVG(UNIX_TIMESTAMP(t.my_date)))
Tenga en cuenta que esta expresión final realmente está haciendo lo mismo... convirtiendo el valor de fecha y hora en una cantidad de segundos desde '1970-01-01 00:00:00' UTC, tomando un promedio numérico de eso, y luego sumando ese promedio número de segundos de regreso a '1970-01-01' UTC, y finalmente convertirlo nuevamente a un DATETIME
valor, representado en la sesión actual time_zone
.
P3:¿Django DateTimeField no está configurado para manejar el promedio?
AVG(datetime)
.