Question

J'ai un champ varchar dans SQL Sever 2005 qui est le stockage d'une valeur temporelle dans le format "hh: mm". Ss.mmmm »

Ce que je veux vraiment faire est de prendre la moyenne en utilisant la fonction intégrée globale de ces valeurs de temps. Cependant, ceci:

SELECT AVG(TimeField) FROM TableWithTimeValues

ne fonctionne pas, depuis (bien sûr) SQL varchars pas la moyenne. Cependant, cette

SELECT AVG(CAST(TimeField as datetime)) FROM TableWithTimeValues

ne fonctionne pas non plus. Pour autant que je peux dire, SQL ne sait pas comment convertir une valeur avec le temps seulement et aucune date dans un champ datetime. J'ai essayé une grande variété de choses pour obtenir SQL pour transformer ce champ en datetime, mais jusqu'à présent, pas de chance.

Quelqu'un peut-il suggérer une meilleure façon?

Était-ce utile?

La solution

SQL Server peut convertir une partie de temps que d'une valeur datetime de chaîne à datetime, mais dans votre exemple, vous avez une précision de 4 décimales. SQL Server 2005 ne reconnaît que 3 places. Par conséquent, vous devez tronquer le plus à droite caractère:

create table #TableWithTimeValues
(
    TimeField varchar(13) not null
)

insert into #TableWithTimeValues
select '04:00:00.0000'
union all
select '05:00:00.0000'
union all
select '06:00:00.0000'

SELECT CAST(TimeField as datetime) FROM #TableWithTimeValues
--Msg 241, Level 16, State 1, Line 1
--Conversion failed when converting datetime from character string.

SELECT CAST(LEFT(TimeField, 12) as datetime) FROM #TableWithTimeValues
--Success!

Cela va convertir des valeurs valides en DATETIME à partir du 1900-01-01. SQL Server calcule les dates en fonction de 1 jour = 1 (entier). Une partie du jour sont alors des portions de la valeur 1 (à savoir heures est de 0,5). Parce que la date n'a pas été précisée dans la conversion, SQL Server reçoit la valeur 0 jours (1900-01-01), qui accueille notre besoin en moyenne la partie du temps.

Pour effectuer une opération d'AVG sur un DATETIME, vous devez d'abord convertir le DATETIME à une valeur décimale, effectuer l'agrégation, puis jeté en arrière. Par exemple

SELECT CAST(AVG(CAST(CAST(LEFT(TimeField, 12) as datetime) AS FLOAT)) AS DATETIME) FROM #TableWithTimeValues
--1900-01-01 05:00:00.000

Si vous devez stocker ce avec une place décimale supplémentaire, vous pouvez convertir le DATETIME à un VARCHAR avec une partie de temps seulement et pad la chaîne de retour à 13 caractères:

SELECT CONVERT(VARCHAR, CAST(AVG(CAST(CAST(LEFT(TimeField, 12) as datetime) AS FLOAT)) AS DATETIME), 114) + '0' FROM #TableWithTimeValues

Autres conseils

Essayer cette

AVG(CAST(CAST('1900-01-01 ' + TimeField AS DateTime) AS Float))

Vous devriez vraiment stocker ces données dans une colonne datetime de toute façon. Il suffit d'utiliser une date cohérente pour cette partie (1/1/1900 est très fréquent). Ensuite, vous pouvez simplement appeler AVG () et ne vous inquiétez pas à ce sujet.

je la réponse de Cadaeic pour obtenir une réponse que je cherchais, donc je pensais que je devrais partager le code ....

Je cherchais une requête qui en moyenne tous mes temps ensemble et me donner un tour global délai d'exécution pour toutes les approbations. Voici une déclaration imbriquée qui vous donne l'AVG pour l'identification individuelle TAT et de et imbriquées un ensemble TAT

SELECT 
-- calculates overall TAT for ALL Approvals for specified period of time
-- depending on parameters of query
CONVERT(VARCHAR, CAST(AVG(CAST(CAST(LEFT(Tat_mins, 12) as datetime) AS FLOAT)) AS DATETIME), 108) + '0'

from 
(
-- tat is for individual approvals 
SELECT 
dbo.credit_application.decision_status,
dbo.credit_application.application_id,
cast(dbo.credit_application.data_entry_complete as date) as'Data Entry Date',
cast(dbo.credit_application.decision_date as DATE) as 'Decision Date',
avg(datediff(minute, dbo.credit_application.data_entry_complete, dbo.credit_application.decision_date)) as 'TAT Minutes',
convert (char(5), DateAdd(minute, Datediff(minute,dbo.credit_application.data_entry_complete, dbo.credit_application.decision_date),'00:00:00'),108) as 'TAT_Mins'
FROM  dbo.credit_application
where Decision_status not in ('P','N')

group by dbo.credit_application.decision_status,
dbo.credit_application.data_entry_complete,
dbo.credit_application.decision_date
--dbo.credit_application.application_id
)bb

Comment pensez-vous en moyenne sur datetime?

Je suppose que vous devez GROUP BY une certaine période (heure?), Et afficher le nombre (*)?

SQL Server stocke les données datetime que 2 entiers de 4 octets, donc un datetime prennent 8 octets. Le premier est jours depuis la date de base et la seconde est millisecondes depuis minuit.

Vous pouvez convertir une valeur datetime à un entier et effectuer des opérations mathématiques, mais la conversion ne retourne que la partie « jours » de la valeur datetime par exemple select convert (int, getdate ()). Il est plus difficile de retourner la partie « temps » comme un entier.

est en utilisant SQL Server 2008 une option pour vous? Cette version dispose d'une nouvelle dédié temps type de données.

Merci, Andy.

Je travaillerais la différence entre toutes les dates et un point arbitraire (01/01/1900), en moyenne, puis l'ajouter à nouveau sur le point arbitraire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top