2016-05-04 5 views
0

J'ai un problème en cours d'exécution d'un script sur une base de données pour obtenir la différence moyenne entre plusieurs VARCHAR qui doivent être convertis en DateTimes, puis prendre la moyenne entre tous les résultats.Comment calculer des moyennes de dates au format VARCHAR à partir de plusieurs lignes?

Mon code est:

SELECT YEAR(b.DateAcknow),AVG(datediff(dd,convert(datetime,b.DateAssign), 
convert(datetime,b.DateResolv))) as DayAverage, 
AVG(datediff(hh,convert(datetime,b.TimeAcknow), 
convert(datetime,b.TimeResolv))) as HourAverage 

FROM  table AS b    
WHERE  (x = y) 
AND YEAR(DateResolv) >= 2006 
AND YEAR(DateResolv) < 2016 
AND b.resolution <>'' 

GROUP BY YEAR(b.DateAcknow) 
ORDER BY YEAR(b.DateAcknow)` 

Le résultat que je reçois ne semble pas logique, beaucoup moins il comprend 1900 qui ne relève pas de mes paramètres de la clause where

Ici, il est :

NULL  42   NULL 
1900  0   12 
2006  7   -5 
2007  6   1 
2008  7   1 
2009  4   1 
2010  2   0 
2011  2   0 
2012  2   0 
2013  2   0 
2014  2   0 
2015  2   0 

Est-ce que je convertis le VARCHAR mal?

Je doute que la moyenne pour des milliers d'entrées de 2010-2015 soit la même chose 2 jours et 0 heures aussi, donc soit je fais quelque chose de mal ou les données sont mauvaises.

+0

Je ne suis pas sûr de ce que vous voulez dire. Mon intention est d'afficher pour chaque année quel est le temps de réponse moyen en jours et en heures. – obizues

+0

Sans données d'exemple, il est difficile de voir ce qui se passe ... pourrait-il être que depuis 2010 toutes les dates sont stockées avec un horodatage vide? Cela expliquerait les différences de 0 heure. En ce qui concerne les jours, si la direction veut que les appels soient fermés après 2 jours, il est possible que la plupart d'entre eux aboutissent à une moyenne de 2 jours (je ne sais pas si AVG renvoie autre chose que int – oerkelens

+0

En outre, vos jours et heures ne font pas partie du même laps de temps, bien que votre phrasé semble impliquer que. – oerkelens

Répondre

1

Vous filtrez par DateResolv et groupez par DateAcknow.

Le filtre et le groupe par les mêmes valeurs Field et NULL et les valeurs hors de la plage doivent disparaître.

+0

J'ai donc fait les changements nécessaires pour me débarrasser des valeurs NULL - bu j'ai toujours la moyenne de 2 jours et la moyenne de 0 heure pour chaque entrée. – obizues

1

Vous voudrez probablement enlever la partie globale et juste courir:

SELECT YEAR(b.DateAcknow) 
, convert(datetime,b.DateAssign) AS DateAssignDateTime 
, convert(datetime,b.DateResolv) AS DateResolveDateTime 
, datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)) AS AssignResolveDayDiff 
, convert(datetime,b.TimeAcknow) AS TimeAcknowDateTime 
, convert(datetime,b.TimeResolv) AS TimeResolveDateTime 
, datediff(hh,convert(datetime,b.TimeAcknow), convert(datetime,b.TimeResolv)) AS AcknowResolveHourDiff 
FROM  table AS b    
WHERE  (x = y) 
AND YEAR(DateAcknow) >= 2006 
AND YEAR(DateAcknow) < 2016 
AND b.resolution <>'' 
ORDER BY YEAR(b.DateAcknow) 

Pour vous assurer que tous vos conversions sont d'abord donner un sens. Ensuite, vous aurez une meilleure compréhension de ce que vous faites en moyenne.

Ensuite, si tous les chèques, votre requête devrait fonctionner correctement (cependant, ne vérifier que mxix » changement de

... 
AND YEAR(DateResolv) >= 2006 
AND YEAR(DateResolv) < 2016 
... 

à

... 
AND YEAR(b.DateAcknow) >= 2006 
AND YEAR(b.DateAcknow) < 2016 
... 

fait sens pour vous.

Si vous cherchez à augmenter la précision de la sortie, essayez de convertir vos datiffs comme suit: Ancien: AVG(datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)))

Nouveau: AVG(Convert(Decimal(10, 5), datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv))))

Votre ancienne requête est en moyenne de jours, arrondie à la valeur entière la plus proche, vous donnant des valeurs comme « 2 ». Ce nouvel ajustement vous donnera des réponses comme "1.51235" jours à la place.

Comme il y a 100k enregistrements de différences (plus et moins), il y a de fortes chances que les moyennes soient proches de zéro si elles suivent une distribution normale ou uniforme. Essayez également: AVG(Convert(Decimal(10, 5), ABS(datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)))))

si vous voulez plutôt la différence absolue. Si vos anciennes données avaient des valeurs "5, -3, 4, -1, 3", alors l'ancienne méthode produirait la moyenne de 2, mais si vous aviez la fonction "ABS" qui travaillait dessus, cela changerait les valeurs à "5, 3, 4, 1, 3" et déplacera votre moyenne résultante dans la direction ++ (ici, elle change en "3", ou "3.2", si vous avez aussi fait votre conversion décimale).

+0

L'exécution de ce que vous avez suggéré renvoie les données correctes. – obizues

+0

Alors pouvez-vous repérer le problème? Peut-être que si vous publiez les résultats de cette requête, et le résultat souhaité de l'agrégat, je pourrais repérer l'erreur logique. Vous devrez peut-être utiliser une fonction ABS sur vos différences, et/ou les convertir en types décimaux avant de faire la moyenne pour obtenir des résultats «appropriés». – Sturgus

+0

Il contient des résultats de données sensibles si malheureusement je ne peux pas le faire. Il retourne également environ 100 000 enregistrements. Les chances qu'ils soient tous en moyenne 2 jours et 0 heures même avec arrondi n'étant pas dans les décimales est honnêtement des chances PowerBall. – obizues

0

Mon intention est d'afficher pour chaque année la réponse moyenne en jours et en heures. - obizues

Si l'on suppose:

  1. DateAcknow est une date varchar avec un horodatage vide (par exemple, "2011/01/15")
  2. TimeAcknow est le temps de varchar correspondant de DateAcknow (par exemple, « 15 : 35")
  3. DateResolve est une date de varchar avec un horodatage vide (par exemple, "16/01/2011"), qui est toujours supérieure ou égale à DateAcknow
  4. TimeResolve est le temps de varchar correspondant de DateResolve (par exemple, « 13 : 47 ")
  5. Vous voulez en moyenne Différence heures (en utilisant l'exemple ci-dessus, la différence des heures de ce disque est 22)

Si vous avez besoin d'aide avec le format de date varchar et la fonction de conversion, voir: http://msdn.microsoft.com/en-us/library/ms187928.aspx

L'approche devrait fonctionner pour atteindre votre intention:

SELECT YEAR(b.DateAcknow) 
, AVG(DateDiff(Day, Convert(datetime, b.DateAcknow) + convert(datetime, b.TimeAcknow), Convert(datetime, b.DateResolv) + Convert(datetime, b.TimeResolve))) AS AvgDaysDifference 
, AVG(DateDiff(Hour, Convert(datetime, b.DateAcknow) + convert(datetime, b.TimeAcknow), Convert(datetime, b.DateResolv) + Convert(datetime, b.TimeResolve))) AS AvgHoursDifference 
FROM  table AS b    
WHERE (x = y) AND YEAR(DateAcknow) >= 2006 AND YEAR(DateAcknow) < 2016 
    AND b.resolution <>'' 
GROUP BY YEAR(b.DateAcknow) 

Cela devrait le faire si les hypothèses sur vos données et votre intention sont corrects. Il est difficile d'aider quand ce n'est pas clair.