Choisir entre une durée et des jours calendaires
Une commande passée avant minuit et approuvée quelques minutes après change de date, sans avoir attendu une journée. Selon la question métier, tu peux vouloir mesurer le temps écoulé ou le nombre de dates traversées.
Cette fiche travaille l'extraction d'un résultat avec SQL (BC01) et son interprétation (BC02).
| Ton besoin | Où travailler |
|---|---|
| Distinguer les deux mesures | Sections 1 et 2 |
| Choisir une définition et la vérifier | Section 3 |
1. Observer une commande qui traverse minuit
Avant d'exécuter, prédis les deux valeurs obtenues pour une commande approuvée sept minutes après son achat, mais le jour suivant.
SELECT order_purchase_timestamp AS achat,
order_approved_at AS approbation,
order_approved_at - order_purchase_timestamp AS duree,
order_approved_at::date - order_purchase_timestamp::date AS jours_calendaires
FROM orders
WHERE order_approved_at::date > order_purchase_timestamp::date
AND order_approved_at - order_purchase_timestamp < interval '10 minutes'
ORDER BY duree
LIMIT 3;Voici la première ligne :
| achat | approbation | duree | jours_calendaires |
|---|---|---|---|
| 2018-07-16 23:53:40 | 2018-07-17 00:00:52 | 00:07:12 | 1 |
La durée mesure 7 minutes et 12 secondes. Le calcul sur les dates compte une bascule de minuit. Les deux valeurs sont exactes, mais elles ne décrivent pas la même chose.
2. Lire ce que PostgreSQL calcule
SELECT pg_typeof(order_approved_at - order_purchase_timestamp) AS type_duree,
pg_typeof(order_approved_at::date - order_purchase_timestamp::date) AS type_jours
FROM orders
WHERE order_approved_at IS NOT NULL
LIMIT 1;| Soustraction | Résultat | Question mesurée |
|---|---|---|
timestamp - timestamp |
un interval |
Combien de temps s'est écoulé ? |
date - date |
un entier | Combien de dates ont été traversées ? |
Un timestamp contient une date et une heure. ::date retire l'heure avant la
soustraction. Cette conversion ne fait donc pas qu'arrondir une durée : elle
change la question.
Compare maintenant les deux définitions sur les approbations :
SELECT COUNT(*) FILTER (
WHERE order_approved_at - order_purchase_timestamp < interval '24 hours'
) AS moins_de_24_heures,
COUNT(*) FILTER (
WHERE order_approved_at::date = order_purchase_timestamp::date
) AS meme_date
FROM orders
WHERE order_approved_at IS NOT NULL;Avant d'exécuter, prédis quel compteur sera le plus grand. Une approbation qui traverse minuit en quelques minutes appartient au premier groupe, mais pas au second. Le résultat permet de vérifier ta prédiction.
3. Choisir avant de calculer
Écris d'abord l'une de ces deux phrases avec tes propres mots :
- « Je mesure le temps réellement écoulé entre deux événements. »
- « Je compte les jours du calendrier entre deux dates. »
Choisis ensuite les colonnes d'une requête de ton TP et écris le calcul adapté. Ne calcule pas encore le résultat final attendu par la question : commence par afficher quelques lignes avec les deux dates et leur différence.
SELECT date_debut,
date_fin,
date_fin - date_debut AS ecart
FROM nom_de_la_table
WHERE date_debut IS NOT NULL
AND date_fin IS NOT NULL
ORDER BY ecart
LIMIT 10;Si tu bloques, regarde la façon dont l'engagement est formulé. « Sous 72 heures » appelle une durée. « Avant le 12 » ou « sous trois jours calendaires » appelle une comparaison de dates.
Pour vérifier ton choix, cherche une ligne proche de minuit. Explique si elle doit compter comme quelques minutes ou comme un changement de jour dans la question traitée. Garde cette définition en commentaire SQL avec ton résultat.
Le bac à sable affiche au maximum 200 lignes. Pour vérifier un effectif complet,
utilise COUNT(*) plutôt que le nombre de lignes visibles.