1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| WITH
v_periode_duree -- Extraire le jour et calculer la durée de chaque période
AS ( SELECT id_emp
, CAST(TRUNC(heure_debut, 'ddd') AS DATE) AS jour
, (heure_fin - heure_debut) DAY TO MINUTE AS duree
FROM v_periode_detail
)
, v_periode_detail -- Découper les périodes qui chevauchent sur deux jours
AS ( SELECT id_emp
, heure_debut
, heure_fin
FROM v_periode_brute
WHERE TRUNC(heure_debut, 'ddd') = TRUNC(heure_fin, 'ddd') -- Début et fin le même jour
UNION ALL
SELECT id_emp
, heure_debut
, TRUNC(heure_fin, 'ddd') AS heure_fin -- Jusqu'à la fin de la journée
FROM v_periode_brute
WHERE TRUNC(heure_debut, 'ddd') < TRUNC(heure_fin, 'ddd') -- Fin un autre jour
UNION ALL
SELECT id_emp
, TRUNC(heure_fin, 'ddd') AS heure_debut
, heure_fin
FROM v_periode_brute
WHERE TRUNC(heure_debut, 'ddd') < TRUNC(heure_fin, 'ddd') -- Fin un autre jour
AND TRUNC(heure_fin, 'ddd') < heure_fin -- Cas particulier
)
, v_periode_brute -- Associer l'heure de début à l'heure de fin
AS ( SELECT deb.id_emp
, deb.heure AS heure_debut
, MIN(fin.heure) AS heure_fin -- La plus petite des heures de fin postérieures à l'heure de début
FROM v_heure_debut AS deb
INNER JOIN
v_heure_fin AS fin
ON deb.id_emp = fin.id_emp
AND deb.heure < fin.heure
GROUP BY 1,2
)
, v_heure_debut
AS ( SELECT employenr as id_emp
, c_timestamp as heure -- TIMESTAMP est un mot réservé du langage SQL, Teradata devrait le refuser
FROM TABLE
WHERE f_type = 'start'
)
, v_heure_fin -- Seulement les heures de fin de période
AS ( SELECT employenr as id_emp
, c_timestamp as heure
FROM TABLE
WHERE f_type IN ('stop', 'pause')
)
SELECT
id_emp
, jour AS f_day
, SUM(duree) AS f_hours
FROM v_periode_duree AS per
HAVING
jour >= '2017-01-01'
GROUP BY 1,2,3
ORDER BY 2,3 DESC; |
Partager