2016-05-04 8 views
0

У меня проблема, когда я запускаю скрипт против базы данных, чтобы получить среднее различие между несколькими VARCHAR, которые необходимо преобразовать в DateTimes, а затем взять среднее значение между всеми результатами.Как рассчитать средние даты, отформатированные как VARCHAR из нескольких строк?

Мой код:

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

В результате я получаю, кажется, не имеет смысла, гораздо меньше, она включает в себя 1900, которая выходит за пределы моих параметров где п

Здесь :

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 

Я преобразовываю VARCHAR s неправильно?

Сомневаюсь, что в среднем за тысячи записей в 2010-2015 годах все равно 2 дня и 0 часов, так что либо я делаю что-то неправильно, либо данные плохие.

+0

Я не уверен, что вы имеете в виду. Мое намерение состоит в том, чтобы отображать на каждый год, что среднее время отклика в днях и часах. – obizues

+0

Без примеров данных трудно понять, что происходит ... может быть, с 2010 года все даты хранятся с пустой меткой времени? Это объясняет разницу в 0 часов. Что касается дней, если менеджмент хочет, чтобы звонки закрывались через 2 дня, вполне возможно, что большинство из них, что приводит к среднему из двух дней (я не знаю, вернет ли AVG что-либо, кроме int, если вы усредняете целые числа?) – oerkelens

+0

Кроме того, ваши дни и часы не входят в один и тот же промежуток времени, хотя ваша фразировка, по-видимому, подразумевает это. – oerkelens

ответ

1

Вы фильтруете DateResolv и group by DateAcknow.

Фильтр и группа по тому же полю и NULL, а значения за пределами диапазона должны исчезнуть.

+0

Итак, я сделал правильные изменения, чтобы избавиться от значений NULL. Буква tI по-прежнему имеет средние 2 дня и среднее значение за 0 часов для каждой записи. – obizues

1

Вы, вероятно, хотите, чтобы забрать часть совокупной и просто запустите:

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) 

Чтобы убедиться, что все ваши преобразования делает смысл первым. Тогда у вас будет лучшее понимание того, что именно вы на самом деле усредняете.

Затем, если он все проверяет вне, то ваш запрос должен работать нормально (хотя, не проверить, что mxix»переход от

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

в

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

имеет смысл для вас.

Если вы хотите увеличить точность вывода, попробуйте конвертировать ваши датиффы так: Old: AVG(datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)))

Новые: AVG(Convert(Decimal(10, 5), datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv))))

Ваш старый запрос в среднем дней, округляются до ближайшего целого значения, что дает вам значение, как «2». Эта новая корректировка даст вам ответы типа «1.51235» дней.

Поскольку существует 100 тыс. Записей различий (как плюс, так и минус), есть вероятность, что средние значения будут близки к нулю, если они будут следовать нормальному или равномерному распределению. Также попробуйте: AVG(Convert(Decimal(10, 5), ABS(datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)))))

если вы хотите абсолютную разницу. Если ваши старые данные имели значения «5, -3, 4, -1, 3», тогда старый метод выдавал среднее значение 2, но если бы у вас была функция «ABS», работая над ними, это изменило бы значения на «5, 3, 4, 1, 3» и переместит полученное среднее значение в направлении ++ (здесь он изменится на «3» или «3.2», если вы тоже сделали десятичное преобразование).

+0

Выполнение того, что вы предложили, вернет правильные данные. – obizues

+0

Так вы можете определить проблему? Возможно, если вы опубликуете результаты этого запроса и желаемый результат совокупности, я могу обнаружить логическую ошибку. Возможно, вам придется использовать функцию ABS для своих различий и/или преобразовать их в десятичные типы до усреднения, чтобы получить «соответствующие» результаты. – Sturgus

+0

Он содержит чувствительные данные, поэтому, к сожалению, я не могу этого сделать. Он также возвращает около 100 000 записей. Шансы, что все они средние 2 дня и 0 часов, даже с округлением, не находящимися в десятичных знаках, - это честно шансы PowerBall. – obizues

0

Мое намерение состоит в том, чтобы отображать на каждый год, какой средний ответ раз в Дней и Часах. - obizues

Предполагая, что:

  1. DateAcknow является дата VARCHAR с пустой меткой времени (например, "2011/01/15")
  2. TimeAcknow является соответствующее время VARCHAR DateAcknow (например, «15 : 35")
  3. DateResolve является дата VARCHAR с пустой меткой времени (например, „2011/01/16“), который всегда больше или равна DateAcknow
  4. TimeResolve является соответствующее время VARCHAR DateResolve (например, «13 : 47 ")
  5. Вы хотите усреднить общую разницу часов (с использованием приведенного выше примера, разница часов этой записи является 22)

Если вам нужна помощь с форматом вашей даты VARCHAR и функцией новообращенного, см: http://msdn.microsoft.com/en-us/library/ms187928.aspx

следующий подход должен работать для достижения вашего намерения:

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) 

Это следует делать, если предположения о ваших данных и вашего намерения являются правильными. Трудно помочь, когда это не ясно.