Intervalle de temps postgres

J'ai une table qui contient l'identifiant (unique), l'identifiant du système, l'horodatage et le statut. Lorsque le statut 1 signifie, système indisponible, lorsque 0 - disponible:

CREATE temp TABLE temp_data_test (
id int8 NULL,
system_id int8 NULL,
time timestamptz NULL,
status int4 NULL
);

INSERT INTO temp_data_test (id, system, time, status) VALUES
(53,1,'2022-04-02 13:57:07.000',1),
(54,1,'2022-04-02 14:10:26.000',0),
(55,1,'2022-04-02 14:28:45.000',1),
(56,1,'2022-04-02 14:32:19.000',0),
(57,1,'2022-04-05 03:20:18.000',1),
(58,3,'2022-04-05 03:21:18.000',1),
(59,2,'2022-04-05 03:21:22.000',1),
(60,2,'2022-04-06 02:27:15.000',0),
(61,3,'2022-04-06 02:27:15.000',0),
(62,1,'2022-04-06 02:28:17.000',0);

Cela fonctionne comme lorsque le système devient indisponible, nous obtenons 1, lorsqu'il devient disponible -> 0. J'ai besoin d'obtenir un tableau de résultats quand je peux voir combien d'heures chaque jour chaque système était indisponible. Pour ce tableau, le résultat devrait être

date system  available  unavailable
2022-04-02 1 13:57:07+00:18:19+09:27:40 =23:43:06 23:59:59-23:43:06=..
2022-04-02 2 24 0
2022-04-02 3 24 0
2022-04-03 1 24 0
2022-04-03 2 24 0
2022-04-03 3 24 0
...
2022-04-05 1 03:20:18 23:59:59-03:20:18=..
2022-04-05 3 03:21:18 23:59:59-03:21:18=..
2022-04-05 2 03:21:22 23:59:59-03:21:22=..
2022-04-06 1 23:59:59-02:28:17=.. 02:28:17
2022-04-06 3 23:59:59-02:27:15=.. 02:27:15
2022-04-06 2 23:59:59-02:27:15=.. 02:27:15

J'essaie de le faire avec plus de partition et de récursivité, mais j'obtiens plus d'intervalle que nécessaire.


Solution du problème

J'ai écrit un exemple de requête pour calculer les intervalles et afficher les intervalles sous forme d'heures en utilisant la structure de votre table :

with d_test as (
select
row_number() over (order by system_id, time) as r_num,
"time"::date as "onlydate",
"time",
system_id,
status
from temp_data_test
order by system_id, time
)
select avi.*, unavi."unavialible", unavi."unavialible_hours" from (
select
d1.system_id,
d1.onlydate,
sum(d2.time - d1.time) as "avialible",
(extract(day from sum(d2.time - d1.time) )*24 + extract(hour from sum(d2.time - d1.time)))::text || ' hours' as "avialible_hours"
from d_test d1
inner join d_test d2 on d1.r_num+1 = d2.r_num and d1.system_id = d2.system_id
where d1.status = 1
group by d1.system_id, d1.onlydate
order by d1.system_id
) avi
left join (
select
d1.system_id,
d1.onlydate,
sum(d2.time - d1.time) as "unavialible",
(extract(day from sum(d2.time - d1.time) )*24 + extract(hour from sum(d2.time - d1.time)))::text || ' hours' as "unavialible_hours"
from d_test d1
inner join d_test d2 on d1.r_num+1 = d2.r_num and d1.system_id = d2.system_id
where d1.status = 0
group by d1.system_id, d1.onlydate
order by d1.system_id
) unavi on avi.system_id = unavi.system_id and avi.onlydate = unavi.onlydate

Résultat de cette requête :














































system_idseule datedisponibleheures_disponiblesnon disponibleunavialible_hours
une2022-04-0200:16:530 heures2 jours 13:06:1861 heures
une2022-04-0523:07:5923 heures
22022-04-0523:05:5323 heures
32022-04-051 jour 02:05:5726 heures

Commentaires

Posts les plus consultés de ce blog

Erreur Symfony : "Une exception a été levée lors du rendu d'un modèle"

Détecter les appuis sur les touches fléchées en JavaScript

Une chaîne vide donne "Des erreurs ont été détectées dans les arguments de la ligne de commande, veuillez vous assurer que tous les arguments sont correctement définis"