Yo propondría una solución en dos partes: Primero recuperar la diferencia de tiempo con TIMESTAMDIFF(), tal y como proponen todo, pero implementar la salida de la cadena final por medio de una Stored Function, de modo de tener un código más limpio y comprensible:
Código sql:
Ver originalSELECT FN_DEVOLVERTIEMPO(TIMESTAMPDIFF(SECOND, '2007-12-30 11:23:24', '2007-12-31 23:59:59'));
Función:
Código sql:
Ver originalDELIMITER $$
DROP FUNCTION IF EXISTS `FN_DEVOLVERTIEMPO` $$
CREATE FUNCTION `FN_DEVOLVERTIEMPO`(TOTALSEG INT) RETURNS CHAR(32) CHARSET latin1
READS SQL DATA
BEGIN
DECLARE TIEMPO CHAR(32);
DECLARE DIA INT DEFAULT 0;
DECLARE HORA INT DEFAULT 0;
DECLARE MINUTO INT DEFAULT 0;
DECLARE SEGUNDO INT DEFAULT 0;
SET DIA= TOTALSEG DIV 86400;
SET TOTALSEG = TOTALSEG % 86400;
SET HORA= TOTALSEG DIV 3600;
SET TOTALSEG = TOTALSEG % 3600;
SET MINUTO = TOTALSEG DIV 60;
SET SEGUNDO= TOTALSEG % 60;
SET TIEMPO=CONCAT(DIA, ' D. ', HORA, ' hs. ', MINUTO,' min. ', SEGUNDO,' seg.');
RETURN TIEMPO;
END $$
DELIMITER ;
La función tiene una redacción poco eficiente pero cumple su cometido: entrega un string con la representación completa en una cadena (tiene esa forma porque la aplicación en que se usa requiere que la salida sea así).
Si se requiere que los valores vuelvan por separado, habría que darle forma de Stored Procedure:
Código SQL:
Ver originalDELIMITER $$
DROP PROCEDURE IF EXISTS `SP_DEVOLVERTIEMPO` $$
CREATE PROCEDURE `SP_DEVOLVERTIEMPO`(
IN TOTALSEG INT,
OUT DIA INT,
OUT HORA INT,
OUT MINUTO INT
OUT SEGUNDO INT
) RETURNS CHAR(32) CHARSET latin1
READS SQL DATA
BEGIN
SET DIA= TOTALSEG DIV 86400;
SET TOTALSEG = TOTALSEG % 86400;
SET HORA= TOTALSEG DIV 3600;
SET TOTALSEG = TOTALSEG % 3600;
SET MINUTO = TOTALSEG DIV 60;
SET SEGUNDO= TOTALSEG % 60;
END $$
DELIMITER ;
En ese caso, habría que llamarla por CALL y recoger la salida en sendas variables.