Pregunta

Tengo un campo varchar en SQL Sever 2005 que está almacenando un valor de tiempo en el formato "hh: mm". Ss.mmmm"

Lo que realmente quiero hacer es tomar el promedio utilizando el construido en función de agregación de esos valores de tiempo. Sin embargo, esto:

SELECT AVG(TimeField) FROM TableWithTimeValues

no funciona, ya que (por supuesto) SQL varchars no son promedio. Sin embargo, esto

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

también no funciona. Lo más cerca que puedo decir, SQL no sabe cómo convertir un valor con sólo el tiempo y no hay fecha en un campo de fecha y hora. He probado una gran variedad de cosas para conseguir SQL para convertir a ese respecto en una fecha y hora, pero hasta ahora, no hubo suerte.

Puede alguien sugerir una mejor manera?

¿Fue útil?

Solución

SQL Server puede convertir una porción sola vez de un valor de fecha y hora de la cadena a fecha y hora, sin embargo, en el ejemplo, tiene una precisión de 4 decimales. SQL Server 2005 sólo reconoce 3 lugares. Por lo tanto, será necesario truncar el más adecuado caracteres:

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!

Esto convertirá valores válidos en una fecha y hora que comienza el 1900-01-01. SQL Server calcula fechas basado en 1 día = 1 (entero). Las porciones del día son entonces porciones del valor 1 (es decir, el mediodía es 0,5). Debido a una fecha no se ha especificado en la conversión, SQL Server asigna el valor de 0 días (1900-01-01), que da cabida a nuestra necesidad de promediar la porción de tiempo.

Para realizar una operación de AVG en una fecha y hora, primero debe convertir la fecha y hora a un valor decimal, realizar la agregación, a continuación, echó hacia atrás. Por ejemplo

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

Si necesita almacenar esto con una posición decimal adicional, puede convertir la fecha y hora a un VARCHAR con la porción de tiempo única y la almohadilla de la cadena de nuevo a 13 caracteres:

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

Otros consejos

Probar

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

Usted realmente debe almacenar los de una columna de fecha y hora de todos modos. Sólo tiene que utilizar una fecha uniforme con la parte (1/1/1900 es muy común). A continuación, sólo puede llamar a AVG () y no se preocupan por él.

He utilizado la respuesta de Cadaeic para obtener una respuesta que estaba buscando, así que pensé que debería compartir el código ....

Yo estaba buscando una consulta que promedio Todos mis momentos juntos y me da un giro total a la hora de todas las aprobaciones. A continuación se muestra una declaración anidada que proporciona la AVG TAT para el individuo de identificación y anidado y cuando un general 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

¿Cómo cree que en un promedio de fecha y hora?

supongo que tiene que GROUP BY algún período (horas?), Y el recuento de display (*)?

SQL Server almacena los datos de fecha y hora como 2 enteros de 4 bytes, por lo tanto, una fecha y hora tomar de 8 bytes. La primera es días desde la fecha de referencia y el segundo es milisegundos desde la medianoche.

Puede convertir un valor de fecha y hora a un número entero y realizar operaciones matemáticas, pero el convertido sólo devuelve la parte de "día" del valor de fecha y hora, por ejemplo, select convert (int, getdate ()). Es más difícil de devolver la parte "tiempo" como un entero.

Está utilizando SQL Server 2008 una opción para usted? Esa versión tiene un nuevo dedicado tiempo tipo de datos.

Gracias, Andy.

Yo trabajo la diferencia entre todas las fechas y un punto arbitrario (01/01/1900), promedio y luego añadirlo de nuevo en el punto arbitrario.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top