2016-05-04 14 views
0

Ich habe ein Problem, bei dem ich ein Skript für eine Datenbank ausführe, um den durchschnittlichen Unterschied zwischen mehreren VARCHARs zu ermitteln, die in DateTimes konvertiert werden müssen, und dann den Durchschnitt zwischen allen Ergebnissen zu ermitteln.Wie berechne ich Durchschnittswerte von Daten, die als VARCHAR aus mehreren Zeilen formatiert sind?

Mein Code ist:

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)` 

Das Ergebnis, das ich bin nicht immer Sinn zu machen scheint, viel weniger es das Jahr 1900, die außerhalb meiner Parameter der Where-Klausel fällt

Hier ist :

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 

Ändere ich die VARCHAR s falsch?

Ich bezweifle, dass der Durchschnitt für Tausende von Einträgen von 2010-2015 sind alle gleich 2 Tage und 0 Stunden zu, so entweder ich mache etwas falsch oder die Daten sind schlecht.

+0

Ich bin mir nicht sicher, was du meinst. Mein Ziel ist es, für jedes Jahr die durchschnittliche Antwortzeit in Tagen und Stunden anzuzeigen. – obizues

+0

Ohne Beispieldaten ist es schwierig zu sehen, was passiert ... könnte es sein, dass seit 2010 alle Daten mit einem leeren Zeitstempel gespeichert sind? Das würde die Unterschiede von 0 Stunden erklären. An den Tagen, wenn das Management möchte, dass Anrufe nach 2 Tagen geschlossen werden, ist es gut möglich, dass die meisten von ihnen sind, was zu einem Durchschnitt von 2 Tagen führt (ich weiß nicht, ob AVG alles zurückgibt, außer int, wenn Sie ganzzahlig sind?) – oerkelens

+0

Auch Ihre Tage und Stunden sind nicht Teil der gleichen Zeitspanne, obwohl Ihre Formulierung dies zu implizieren scheint. – oerkelens

Antwort

1

Sie filtern nach DateResolv und gruppieren nach DateAcknow.

Filter und Gruppe mit dem gleichen Feld und NULL und Werte außerhalb des Bereichs sollten verschwinden.

+0

Also habe ich die richtigen Änderungen vorgenommen, um die NULL-Werte loszuwerden - aber ich habe immer noch den 2-Tage-Durchschnitt und den 0-Stunden-Durchschnitt für jeden Eintrag. – obizues

1

Sie werden wahrscheinlich wollen das Aggregat Teil wegzunehmen und laufen einfach:

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) 

Um sicherzustellen, dass alle Ihre Conversions ersten Sinn machen. Dann werden Sie ein besseres Verständnis davon haben, was Sie tatsächlich berechnen.

Danach, wenn er alle Prüfungen, dann sollten Sie Ihre Abfrage funktionieren (obwohl, überprüfen, dass mxix‘Wechsel von

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

zu

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

macht Sinn für Sie.

Wenn Sie die Genauigkeit der Ausgabe erhöhen möchten, dann versuchen Sie, Ihre datendiffs wie folgt zu konvertieren: Alt: AVG(datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)))

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

Ihre alte Abfrage ist mit durchschnittlich Tage, gerundet auf die nächste ganze Zahl, Sie Werte wie ‚2‘ geben. Diese neue Anpassung gibt Ihnen stattdessen Antworten wie "1.51235" Tage.

Da es 100k Datensätze von Unterschieden (plus und minus) gibt, besteht eine gute Chance, dass die Durchschnittswerte nahe Null liegen, wenn sie einer normalen oder gleichmäßigen Verteilung folgen. Versuchen Sie auch: AVG(Convert(Decimal(10, 5), ABS(datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)))))

wenn Sie absolute Unterschied stattdessen wollen. Wenn Ihre alten Daten die Werte "5, -3, 4, -1, 3" hätten, würde die alte Methode den Durchschnitt von 2 ergeben, aber wenn Sie die "ABS" -Funktion hätten, würde sie die Werte ändern "5, 3, 4, 1, 3" und verschiebt den resultierenden Mittelwert in die Richtung ++ (hier ändert er sich zu "3", oder "3.2", wenn Sie auch Ihre Dezimalkonvertierung durchgeführt haben).

+0

Wenn Sie ausführen, was Sie vorgeschlagen haben, werden die richtigen Daten zurückgegeben. – obizues

+0

Also können Sie das Problem erkennen? Vielleicht könnte ich den logischen Fehler finden, wenn Sie die Ergebnisse dieser Abfrage und das gewünschte Ergebnis des Aggregats posten würden. Möglicherweise müssen Sie eine ABS-Funktion für Ihre Differenzen verwenden und/oder vor der Mittelwertbildung in Dezimaltypen konvertieren, um "geeignete" Ergebnisse zu erhalten. – Sturgus

+0

Es enthält sensible Daten Ergebnisse, so traurig kann ich das nicht tun. Es gibt ungefähr 100.000 Datensätze zurück. Die Chancen, dass sie alle durchschnittlich 2 Tage und 0 Stunden sind, auch wenn das Runden nicht in den Dezimalzahlen liegt, ist ehrlich gesagt die PowerBall-Quote. – obizues

0

Meine Absicht ist es, für jedes Jahr anzuzeigen, was die durchschnittliche Antwort Zeit in Tagen und Stunden ist. - obizues

Unter der Annahme:

  1. DateAcknow ist ein VARCHAR Datum mit einem leeren Zeitmarke (zB "2011.01.15")
  2. TimeAcknow entsprechen VARCHAR Zeit des DateAcknow (zum Beispiel 15“ : 35")
  3. DateResolve ist mit einem leeren Zeitmarke (zB ein VARCHAR date "2011.01.16"), die immer größer als oder gleich ist DateAcknow
  4. TimeResolve ist DateResolve der entsprechende VARCHAR Zeit (zB „13 : 47 ")
  5. Sie insgesamt Stunden Differenz (mit dem obigen Beispiel dieses Rekords Stunden Differenz ist 22)

Wenn Sie mit Ihrem varchar Datum des Format und der Funktion convert helfen müssen im Durchschnitt wollen, finden Sie unter: http://msdn.microsoft.com/en-us/library/ms187928.aspx

Der folgende Ansatz sollte arbeiten, um Ihre Absicht zu erreichen:

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) 

Dies sollte es tun, wenn die Annahmen über Ihre Daten und Ihre Absicht korrekt sind. Es ist schwer zu helfen, wenn es nicht klar ist.