PDA

Ver la Versión Completa : Sumar tiempos con SUM


Ruben_Cu
01-11-2003, 06:35:08
Hola a todos, estoy haciendo una aplicación para el manejo de información de una pizarra telefónica que entre otras cosas debe sumar los tiempos usados por cada extensión y pasarlos a un gráfico TChart.
La BD es paradox 7 y he tratado de hacer lo siguiente:
select extension, sum(duracion) as tiempo from bdtelf
order by extension
Con esta declaración obtengo el error:
Type mismatch in expression
Como pienso que este error se debe a incongruencia entre la función SUM y lo que tiene que sumar, que son valores de un campo tipo TTimeField traté de utilizar la función CAST y acomodarlo así:
select extension, sum(cast(duracion as FLOAT)) as tiempo from bdtelf
order by extension
Pero me vuelve a aparecer el error, ¿alguna idea o ayuda de como sumar los tiempos por extensión?
Como dato adicional ellos aparecen en la tabla con formato 00:00:00
Gracias por su tiempo

roman
01-11-2003, 07:08:04
Después de algunos intentos me parece que no puedes convertir un campo TIMEa un campo numérico, sólo a uno de tipo caracter.

Lo único que se me ocurre ahora es convertirlo a CHAR(8), usar SUBSTRING para separar cada parte (hora, minutos y segundos) y convertirla cada una a NUMERIC. Multiplicar la parte de horas por 3600 y la parte de minutos por 60 y sumar todas las partes para obtener el número de segundos que dura cada llamada. Sobre este resultado hacer la SUM. En resumen, algo así:



select
extension,
sum(
cast(substring(cast(duracion as char(8)) from 1 for 2) as numeric)*3600 +
cast(substring(cast(duracion as char(8)) from 4 for 2) as numeric)*60 +
cast(substring(cast(duracion as char(8)) from 7 for 2) as numeric)
)
from
bdtelf
group by
extension


Por cierto, era GROUP BY en lugar de ORDER BY.

Desde luego, una vez hecha la consulta tendrías que descomponer el número de segundos en horas, minutos y segundos.

// Saludos

marcoszorrilla
02-11-2003, 20:33:11
He estado desarrollando la excelente idea de Román y he llegado hasta sumar horas y minutos, lo he dejado ahí, porque me parece que el código deviene demasiado farragoso.


select
extension,
sum((
cast(substring(cast(tiempo as char(8)) from 1 for 2) as Integer)*3600 +
cast(substring(cast(tiempo as char(8)) from 4 for 2) as Integer)*60 +
cast(substring(cast(tiempo as char(8)) from 7 for 2) as Integer)
) /3600) as ttHoras,


sum((
cast(substring(cast(tiempo as char(8)) from 1 for 2) as Integer)*3600 +
cast(substring(cast(tiempo as char(8)) from 4 for 2) as Integer)*60 +
cast(substring(cast(tiempo as char(8)) from 7 for 2) as Integer)
) /60) -

sum(((
cast(substring(cast(tiempo as char(8)) from 1 for 2) as Integer)*3600 +
cast(substring(cast(tiempo as char(8)) from 4 for 2) as Integer)*60 +
cast(substring(cast(tiempo as char(8)) from 7 for 2) as Integer)
) /3600) * 60) as ttMinutos

from "d:\pruebas\ruben.db"
group by
extension


Dada la casi nula posibilidad de sumar tiempos con Pardox, yo crearía una rutina, para hacer las sumas mediante un bucle, la acumulación dependiendo de los casos, pudiera ser en un StringGrid, o en una tabla creada al efecto.

Un Saludo.

roman
02-11-2003, 23:07:34
¡Vaya marcoszorrilla! ¡Tú sí que eres atrevido! :D

Diste el paso que yo no me atreví a dar.

Lo que en realidad haría yo es guardar la duración de cada llamada no en un campo TIME sino en un campo NUMERIC guardando el número de milisegundos y dejaría que la aplicación se encargue de hacer las conversiones al guardar y leer. De esta forma, la consulta sería como en un principio:


SELECT
extension,
sum(duracion)
FROM
bdtelf
GROUP BY
extension


y la aplicación simplemente convertiría el resultado de la consulta al formato hh:mm:ss

// Saludos

Ruben_Cu
03-11-2003, 03:10:49
Hola roman y marcos, como estoy desarrollando la aplicación y sus tablas voy a probar (si puedo) mañana una solución que me parece que puede resolver el problema, como recibo una cadena desde la centralita que contiene toda la información de la llamada a través del puerto serie y la descompongo en subcadenas que paso al campo que corresponda voy a tomar la cadena correspondiente a la duración de la llamada y ademas de presentarla en formato 00:00:00 para el usuario, en otro campo que he creado voy a guardar ese valor como numérico (como proponía roman) y entonces es fácil aplicar la función SUM.
Problemas??
El valor almacenado como float es fracción del día y al ser mayor que '1' devuelve el tiempo como si no hubiesen acumuladas 24 horas, por ejemplo es lo mismo 0.5 que 1.5 y 2.5 siempre devuelve las 12:0:0, cuando en realidad debía ser 12:0:0, 36:0:0 y 60:0:0 eso creo que lo he resuelto con una funcioncita, así:
function TiempoUsado(totaltime:double):string;
var Hour, Min, Sec, MSec:word;
begin
DecodeTime(totaltime, Hour, Min, Sec, MSec);
result:= inttostr(hour+trunc(totaltime)*24)+':'+inttostr(min)+':'+inttostr(sec);
end;
Desde el resultado del query le paso el valor del campo SUM .
De esta manera creo que puedo superar la dificultad de no poder sumar campos TTime en paradox.
Diganme si ven alguna cosa rara, pero ha superado las primeras pruebas.
Gracias por su tiempo a ambos y
Saludos