2008-11-20 7 views
2

Je transfère des requêtes depuis Access to T-SQL et ceux qui ont écrit les requêtes ont utilisé la fonction d'agrégation Avg sur les colonnes datetime. Ceci n'est pas supporté par T-SQL et je peux comprendre pourquoi - cela n'a pas de sens. Qu'est-ce qui est en moyenne? Donc, j'étais sur le point de commencer le reverse engineering de ce qu'Access fait quand il agrège datetime en utilisant Avg, mais je pensais que je lancerais la question ici d'abord.Moyenne sur la date et l'heure dans Access

Répondre

3

J'imagine qu'Access fait la moyenne de la représentation numérique des dates. Vous pouvez faire la même dans le T-SQL avec les éléments suivants ...

select AverageDate = cast(avg(cast(MyDateColumn as decimal(20, 10))) as datetime) 
from MyTable 
+0

Oui, c'est ce que j'ai supposé et c'est probablement la chose la plus logique. Je me demandais si ce n'était peut-être pas une sorte de partitionnement comme le temps moyen de la journée ou quelque chose comme ça. –

+0

Un champ de date Jet est un nombre entier pour le jour plus une valeur décimale pour l'heure. Si vous voulez faire la moyenne uniquement sur les dates, utilisez la valeur entière. –

+0

MS SQL est similaire - casting vers int vous donnera seulement la moyenne de la partie date –

1

Je suis plus familier avec SGBD non-MS, mais ... Puisque vous ne pouvez pas ajouter deux valeurs DATETIME, vous ne pouvez pas la moyenne ordinaire. Cependant, vous pourriez faire quelque chose de similaire à:

SELECT AVG(datetime_column - TIMESTAMP '2000-01-01 00:00:00.000000') + 
       TIMESTAMP '2000-01-01 00:00:00.000000' 
    FROM table_containing_datetime_column; 

Ce calcule l'intervalle moyen entre le début de 2000 et les valeurs datetime réelles, et ajoute ensuite cet intervalle au début de l'année 2000. Le choix du « début de 2000 est arbitraire; Tant que le datetime soustrait dans la fonction AVG() est ajouté, vous obtenez une réponse sensée.

Cela suppose que le SGBD utilisé prend en charge la notation SQL «timestamp» standard et prend en charge les types INTERVAL de manière appropriée. La différence entre deux valeurs DATETIME ou TIMESTAMP devrait être un INTERVAL (en fait, INTERVAL DAY (9) à SECOND (6), pour être modérément précis, bien que le '9' soit quelque peu discutable).

Lorsqu'elles sont correctement mutilée pour le SGBD je travaille, l'expression 'œuvres':

CREATE TEMP TABLE table_containing_datetime_column 
(
    datetime_column DATETIME YEAR TO FRACTION(5) NOT NULL 
); 

INSERT INTO table_containing_datetime_column VALUES('2008-11-19 12:12:12.00000'); 
INSERT INTO table_containing_datetime_column VALUES('2008-11-19 22:22:22.00000'); 

SELECT AVG(datetime_column - DATETIME(2000-01-01 00:00:00.00000) YEAR TO FRACTION(5)) + 
    DATETIME(2000-01-01 00:00:00.00000) YEAR TO FRACTION(5) 
FROM table_containing_datetime_column; 

Réponse:

2008-11-19 17:17:17.00000 
1

@ David W. Fenton: « Un champ de date Jet est un entier valeur pour le jour plus une valeur décimale pour le temps "- non, une colonne ACE/Jet DATETIME est un FLOAT (synonymes DOUBLE, FLOAT8, IEEEDOUBLE, NUMBER) avec des limites par exemple la valeur maximale DATETIME est # 9999-12-31: 23: 59: 59 # bien que la valeur maximale FLOAT pouvant être convertie en DATETIME soit un peu plus grande, par ex.

SELECT CDBL(CDATE('9999-12-31 23:59:59')) 

retours 2958465.99998843, cependant

SELECT CDATE(CDBL(2958465.9999999997)) 

ne pas d'erreur, alors que

SELECT CDATE(CDBL(2958465.9999999998)) 

Est-ce erreur. Par conséquent, pour préserver les fonctionnalités de SQL Server, je suggère de convertir la colonne DATETIME en FLOAT par exemple.

SELECT CAST(AVG(CAST(MyDateTimeColumn AS FLOAT)) AS DATETIME) 
    from MyTable 
Questions connexes