PDA

Ver la Versión Completa : Sumar tiempos


Angel.Matilla
20-01-2022, 18:18:23
Buenas tardes. A ver si me sé explicar. Tengo esta tabla en FB 2.5:
CREATE TABLE PISTAS (
DISCO INTEGER NOT NULL,
ORDEN_DISCO SMALLINT NOT NULL,
ORDEN_PISTA SMALLINT NOT NULL,
CANCION CHAR(255),
INTERPRETE CHAR(60),
TIEMPO TIME);
Creo que es bastante evidente que se trata de una BB.DD. de discos. Necesito hacer un query que me sume la duración de las pistas; algo así:
SELECT Disco, SUM(Tiempo) FROM Pistas GROUP BY Disco ORDER BY Disco
Pero al porbar en SQL Manager me da este error:
Unsuccessful execution caused by a system error that precludes successful execution of subsequent statements.
Dynamic SQL Error.
Expression evaluation not supported.
Argument for SUM in dialect 3 must be numeric.
¿Cómo podría hacer ese tipo de query? ¿Bastaría con cambiar el dialecto de la BB.DD. al hacer la suma?
Ya sé que podría sacar los tres datos (hora, minutos y segundos) por separado:
SELECT Disco, SUM(EXTRACT(HOUR FROM Tiempo)) Hora, SUM(EXTRACT(MINUTE FROM Tiempo)) Minuto, SUM(EXTRACT(SECOND FROM Tiempo)) Segundo
FROM Pistas
GROUP BY Disco
ORDER BY Disco
pero al hacer luego un EncodeTime es muy fácil que dé error porque, por ejemplo, una de las sumas saldría algo así:
Disco: 9
Hora: 0
Minuto: 38
Segundo: 711

mamcx
20-01-2022, 19:40:08
Ahi tienes que usar es funciones de fecha, no de numero.

Casimiro Notevi
20-01-2022, 20:23:33
¿Seguro que es dialecto 3?
¿Has mirado los datos del campo tiempo con isql? Es para ver el valor real que tiene guardado, sin máscaras.

Neftali [Germán.Estévez]
21-01-2022, 08:33:54
Yo optaría por guardar internamente los tiempos en segundos (en BD).
Luego a la hora de pintarlos sólo tienes que pasarlos a horas, minutos y segundos. Es una cuestión de visualización.

De esa forma puedes usar la funciones tipo SUM sin problemas.

Angel.Matilla
21-01-2022, 10:02:32
Ahi tienes que usar es funciones de fecha, no de numero.
Efectivamente, pero es que en algún sitio había visto que se podía usar el SUM sobre valores de tiempo.
¿Seguro que es dialecto 3?
La definición de la BB.DD. está puesta así:
Ocio->Connected = false;
Ocio->DatabaseName = "Tablas\\Ocio.fdb";
Ocio->SQLDialect = 3;
Ocio->Params->Clear();
Ocio->Params->Add("USER 'sysdba'");
Ocio->Params->Add("PASSWORD 'masterkey'");
Ocio->Params->Add("PAGE_SIZE 4096");
Ocio->Params->Add("DEFAULT CHARACTER SET ISO8859_1 COLLATION ES_ES_CI_AI");
Ocio->CreateDatabase();
Así que sí, es dialecto 3.
;545009']Yo optaría por guardar internamente los tiempos en segundos (en BD).
Luego a la hora de pintarlos sólo tienes que pasarlos a horas, minutos y segundos. Es una cuestión de visualización.

De esa forma puedes usar la funciones tipo SUM sin problemas.
Es una alternativa que no se me había ocurrido pero te obliga a decodificar el tiempo para poder guardarlo en segundos con lo cual al final tienes el mismo trabajo; he optado por el segundo query de mi mensaje (SUM(EXTRACT(HOUR FROM Tiempo)) Hora) y queda así el código:
int Hora, Minuto, Segundo;

Query->Close();
Query->SQL->Text = "SELECT Disco, SUM(EXTRACT(HOUR FROM Tiempo)) Hora,
SUM(EXTRACT(MINUTE FROM Tiempo)) Minuto,
SUM(EXTRACT(SECOND FROM Tiempo)) Segundo
FROM Pistas GROUP BY Disco ORDER BY Disco";
Query->Open();

for (; !Query->Eof; Query->Next())
{
Segundo = Query->FieldByName("Segundo")->AsInteger % 60;
Minuto = Query->FieldByName("Minuto")->AsInteger + (int)Query->FieldByName("Segundo")->AsInteger / 60;
Hora = Query->FieldByName("Hora")->AsInteger + (int)Query->FieldByName("Minuto")->AsInteger / 60;
Minuto = Minuto % 60;
[...]
}
Muchas gracias por todas vuestras sugerencias.

Casimiro Notevi
21-01-2022, 10:52:40
Cierto, estaba pensando al revés, con dialecto 3 no puedes sumar.

mamcx
21-01-2022, 16:37:09
Efectivamente, pero es que en algún sitio había visto que se podía usar el SUM sobre valores de tiempo.


https://firebirdsql.org/refdocs/langrefupd21-intfunc-dateadd.html

Calculos de fechas se hacen con funciones de fecha. Siempre.

Casimiro Notevi
21-01-2022, 17:11:02
La verdad es que yo me he quedado "pillado" porque no me ha funcionado las pruebas que he hecho, sin embargo:


Tipos fecha y hora.
Tabla II.II. Tipos de datos fecha y hora en Firebird
NOMBRE TAMAÑO RANGO/PRECISIÓN DESCRIPCIÓN
DATE 32 bits con signo 01-01-100 a 31-12-9999 Fecha Ejm: 12/10/1977
TIME 32 bits sin signo 0:00:00 a 23:59:59.9999 Hora
TIMESTAMP 64 bits (2x32 bits) 1 jan 100 CE to 28 feb 32768 CE
Incluye la hora y la fecha en dos estructuras de 32 bits
Al estar todos los tipos fecha almacenados como números, es posible, realizar operaciones aritméticas. Así si a un tipo DATE le suma o resta un entero, se obtendrá una nueva fecha con el incremento o decremento en días correspondiente. Si se resta dos fechas, se obtendrá el número de días entre ellas. Si se resta dos horas, se obtendrá el número de segundos entre ellas.

Angel.Matilla
21-01-2022, 17:53:49
La verdad es que yo me he quedado "pillado" porque no me ha funcionado las pruebas que he hecho, sin embargo:
Ese tipo de operaciones (sumarle o restarle a una fecha) lo hago con relativa frecuencia, por ejemplo para encontrar cuando vence un recibo a domiciliar, pero con horas no lo había hecho nunca. Y he hecho alguna prueba sobre una tabla que guarda exclusivamente tiempo; por ejemplo:
SELECT Duracion + 1 FROM Titulos WHERE Tipo = 2 AND Disco = 589
El registro original en ese campo tiene guardado el valor 0:40:01, pero el query no devuelve nada; por lo que se ve sobre campos de tiempo no puede hacerse.

Casimiro Notevi
21-01-2022, 18:02:43
Por lo visto se puede sumar/restar valores a fechas y horas, y se puede restar fechas y devuelve los días entre ellas, pero lo que no se puede, por lo visto, es sumar fechas ni tampoco horas.

Yo habría jurado que se podía.