Come convertire in SQL il numero di secondi in una durata leggibile dall'uomo?
Domanda
In un database SQL faccio alcune selezioni, che ottengono una durata (come risultato di una sottrazione tra due date) in secondi come int. Ma voglio formattare questo risultato in una forma leggibile dall'uomo come 'hh: mm' o 'dd: hh'. È possibile in SQL e come posso realizzarlo?
Soluzione
In SQL 2005, è possibile utilizzare quanto segue:
select convert(varchar(8), dateadd(second, [SecondsColumn], 0), 108)
Che prima converte i secondi in una data dopo il 1900-01-01, quindi ottiene la parte hh: mm: ss.
Se la colonna è più di 24 ore, verrà visualizzata questa opzione, se desideri giorni e quindi ore in quel caso fai semplicemente qualcosa del tipo:
case when SecondsColumn> (24*60*60)
then
cast(datepart(day,datediff(dd, 0, dateadd(second, SecondsColumn, 0))) as varchar(4))
+ 'd' + convert(varchar(2), dateadd(second, SecondsColumn, 0), 108)
else
convert(varchar(8), dateadd(second, SecondsColumn, 0), 108)
end
Altri suggerimenti
Ogni database lo fa diversamente. Uso PostgreSQL e lo fa in questo modo:
select to_char(my_date - my_other_date, 'HH:MM:SS');
Dovrai consultare il manuale del database che stai utilizzando.
Supponendo di avere secondi:
DECLARE @DurationSeconds INT
-- 25h 45m 14s
SET @DurationSeconds = (25 * 3600) + (45 * 60) + (14)
SELECT
@DurationSeconds,
@DurationSeconds / 3600 hours,
@DurationSeconds % 3600 / 60 minutes,
@DurationSeconds % (3600 / 60) seconds
Lascerò il compito di formattarlo così bene per te. : -)
Non esiste uno standard, sebbene molti DBMS abbiano una propria sintassi personalizzata.
In generale è meglio fare un lavoro di formattazione per la leggibilità umana nel livello di presentazione della tua applicazione piuttosto che ovunque vicino al database.
In Oracle SQL:
-- 86,400 seconds in a day
-- 3,600 seconds in an hour
-- 60 seconds in a minute
select duration, -- seconds
trunc((duration)/86400) || ':' || -- dd
trunc(mod(duration,86400)/3600) || ':' || -- hh
trunc(mod(mod(duration,86400),3600)/60) || ':' || -- mm
mod(mod(mod(duration,86400),3600),60) -- ss
as human_readable
from dual
;