Bigquery Calculer Le Temps Entre 2 Timestamp 2 Lignes

Calculateur BigQuery: calculer le temps entre 2 timestamp sur 2 lignes

Simulez rapidement le résultat de TIMESTAMP_DIFF, visualisez l’écart entre deux événements et générez un exemple SQL directement exploitable dans Google BigQuery.

Comment calculer le temps entre 2 timestamp sur 2 lignes dans BigQuery

La requête “bigquery calculer le temps entre 2 timestamp 2 lignes” correspond à un besoin très fréquent en analytique: mesurer le délai entre deux événements qui ne sont pas stockés sur la même ligne. Cela arrive dans les parcours utilisateurs, la logistique, l’observabilité technique, les workflows métier ou les systèmes de paiement. Dans la pratique, vous avez souvent une table d’événements où chaque enregistrement représente un état, une action, une étape de traitement ou un changement de statut. Le défi n’est donc pas simplement d’appliquer TIMESTAMP_DIFF, mais d’aligner correctement les lignes à comparer.

Dans BigQuery, la logique générale est simple: vous devez d’abord identifier les deux timestamps à confronter, puis utiliser TIMESTAMP_DIFF(timestamp_fin, timestamp_debut, unite). Là où les choses deviennent plus techniques, c’est dans la façon de récupérer ces deux timestamps quand ils résident sur deux lignes distinctes. Les méthodes les plus courantes sont LAG(), LEAD() et le self join. Le bon choix dépend de la structure de vos données, de la clé de regroupement et du type d’analyse que vous souhaitez produire.

Principe clé: si vos événements appartiennent à une même entité, comme un utilisateur, une commande ou une session, il faut presque toujours partitionner les données par cette entité avant de calculer l’écart temporel. Sans partition cohérente, les différences calculées peuvent mélanger des lignes qui n’ont aucun lien métier.

La syntaxe de base avec TIMESTAMP_DIFF

La fonction de base dans BigQuery est la suivante:

TIMESTAMP_DIFF(timestamp_fin, timestamp_debut, SECOND)

Elle renvoie un entier dans l’unité choisie. Si vous demandez SECOND, vous obtenez un nombre entier de secondes. Si vous choisissez MINUTE, HOUR ou DAY, BigQuery retourne un entier dans cette unité. C’est important pour l’interprétation: un délai de 59 secondes renvoie 0 si vous mesurez en minutes.

Cas le plus fréquent: comparer chaque ligne à la précédente avec LAG()

Quand vous cherchez le temps entre deux lignes successives d’une même entité, LAG() est souvent la solution la plus propre. Elle permet de récupérer le timestamp de la ligne précédente dans une fenêtre ordonnée. C’est idéal pour analyser les événements successifs d’un utilisateur, les changements d’état d’une commande ou les logs techniques triés par horodatage.

SELECT user_id, event_name, event_ts, LAG(event_ts) OVER ( PARTITION BY user_id ORDER BY event_ts ) AS previous_event_ts, TIMESTAMP_DIFF( event_ts, LAG(event_ts) OVER ( PARTITION BY user_id ORDER BY event_ts ), SECOND ) AS seconds_since_previous_event FROM project.dataset.events;

Cette approche est performante, lisible et très adaptée aux analyses séquentielles. Le point essentiel est la clause PARTITION BY user_id, qui garantit que chaque événement est comparé au précédent du même utilisateur. La clause ORDER BY event_ts détermine l’ordre de comparaison. Si deux événements ont exactement le même timestamp, il est préférable d’ajouter une seconde colonne de tri, comme un identifiant d’événement, pour obtenir un ordre déterministe.

Comparer une ligne à la suivante avec LEAD()

Si votre question métier consiste à connaître le délai jusqu’à l’étape suivante, utilisez LEAD(). C’est le miroir de LAG(). Par exemple, vous pouvez mesurer le temps entre la création d’une commande et sa validation, ou entre un changement d’état et le suivant.

SELECT order_id, status, status_ts, LEAD(status_ts) OVER ( PARTITION BY order_id ORDER BY status_ts ) AS next_status_ts, TIMESTAMP_DIFF( LEAD(status_ts) OVER ( PARTITION BY order_id ORDER BY status_ts ), status_ts, MINUTE ) AS minutes_until_next_status FROM project.dataset.order_status_history;

Cette variante est particulièrement utile pour construire des SLA, calculer la durée passée dans un état ou identifier les étapes lentes d’un pipeline. Comme toujours, la qualité du résultat dépend directement de l’ordre de tri et de la clé de partition.

Quand utiliser un self join

Le self join devient utile lorsque les deux lignes à comparer ne sont pas simplement “la précédente” ou “la suivante”, mais deux types d’événements précis. Exemple classique: calculer le temps entre un événement signup et un événement purchase, ou entre ticket_opened et ticket_closed. Dans ce cas, vous joignez la table sur elle-même en filtrant les types d’événements nécessaires.

SELECT a.user_id, a.event_ts AS signup_ts, b.event_ts AS purchase_ts, TIMESTAMP_DIFF(b.event_ts, a.event_ts, HOUR) AS hours_to_purchase FROM project.dataset.events a JOIN project.dataset.events b ON a.user_id = b.user_id WHERE a.event_name = ‘signup’ AND b.event_name = ‘purchase’ AND b.event_ts > a.event_ts;

Cette méthode est puissante, mais elle peut aussi générer plusieurs correspondances si un utilisateur réalise plusieurs achats. Il faut alors affiner la logique avec des fonctions analytiques, une agrégation ou des critères supplémentaires pour sélectionner la première correspondance pertinente.

Comprendre les unités de temps dans BigQuery

Le choix de l’unité n’est pas anodin. Si vous travaillez sur des latences API, des événements web ou des traitements batch très courts, la seconde est souvent l’unité minimale utile. Pour les workflows métier, la minute ou l’heure suffit souvent. Pour le suivi logistique ou les cycles contractuels, le jour est plus lisible. Le tableau suivant rassemble des conversions exactes, utiles pour interpréter correctement les résultats.

Unité Valeur exacte en secondes Volume exact par jour Usage analytique typique
Microseconde 0,000001 seconde 86 400 000 000 Instrumentation fine, traces applicatives
Milliseconde 0,001 seconde 86 400 000 Temps de réponse, performance web
Seconde 1 seconde 86 400 Logs, files d’attente, événements métiers
Minute 60 secondes 1 440 SLA, support, retail, marketing
Heure 3 600 secondes 24 Opérations, production, e-commerce
Jour 86 400 secondes 1 Logistique, finance, conformité

TIMESTAMP, DATETIME et DATE: ne pas confondre les types

Un autre point critique en BigQuery concerne le type de données. TIMESTAMP représente un instant absolu dans le temps, stocké en UTC. DATETIME représente une date et une heure sans fuseau horaire. DATE ne contient que la date. Si vous essayez de calculer une durée entre des valeurs qui ne portent pas la même sémantique, vous risquez une erreur technique ou, pire, une erreur métier silencieuse.

Type BigQuery Fuseau horaire Niveau de précision Cas d’usage recommandé
TIMESTAMP Oui, instant absolu en UTC Très précis Logs, événements mondiaux, pipelines distribués
DATETIME Non Date + heure locale Planning métier, horaires locaux
DATE Non Jour uniquement Reporting calendaire, agrégations journalières

Si vos données proviennent de plusieurs pays ou systèmes, il est généralement plus sûr de normaliser vos événements en TIMESTAMP. Pour les références officielles sur les standards temporels, vous pouvez consulter les ressources du NIST, l’heure de référence de time.gov et une ressource pédagogique sur les fuseaux horaires de Andrews University.

Les erreurs les plus fréquentes

  • Oublier PARTITION BY et comparer des lignes appartenant à des entités différentes.
  • Utiliser un ordre de tri incomplet et obtenir des résultats non déterministes.
  • Mélanger TIMESTAMP et DATETIME sans conversion explicite.
  • Interpréter une valeur entière en minutes comme un calcul “arrondi” alors qu’il s’agit d’un nombre entier d’unités complètes.
  • Ne pas filtrer les valeurs nulles produites naturellement par LAG() sur la première ligne d’une partition.
  • Effectuer un self join trop large, créant un volume explosif de correspondances.

Exemple robuste avec filtration des nulls

WITH ordered_events AS ( SELECT session_id, event_ts, event_name, LAG(event_ts) OVER ( PARTITION BY session_id ORDER BY event_ts, event_name ) AS previous_event_ts FROM project.dataset.events ) SELECT session_id, event_name, event_ts, previous_event_ts, TIMESTAMP_DIFF(event_ts, previous_event_ts, SECOND) AS delta_seconds FROM ordered_events WHERE previous_event_ts IS NOT NULL;

Cette version est plus propre pour la production, car elle évite de répéter la même fonction analytique plusieurs fois et filtre directement les lignes sans antécédent.

Méthode recommandée selon votre besoin

  1. Si vous comparez chaque événement au précédent: utilisez LAG().
  2. Si vous comparez chaque événement au suivant: utilisez LEAD().
  3. Si vous comparez deux types d’événements spécifiques: utilisez un self join ou une logique d’appariement plus fine.
  4. Si vos données sont internationales: standardisez en TIMESTAMP UTC.
  5. Si l’ordre de tri n’est pas unique: ajoutez une clé secondaire.

Bonnes pratiques de performance dans BigQuery

Sur de gros volumes, la question ne se limite pas à l’exactitude. Il faut aussi penser au coût et à la vitesse d’exécution. Les fonctions analytiques comme LAG() et LEAD() sont souvent préférables au self join quand vous travaillez sur des comparaisons séquentielles, car la logique est plus directe et le plan d’exécution plus lisible. Il reste cependant indispensable de limiter le périmètre lu par la requête.

  • Partitionnez vos tables sur une colonne temporelle si cela correspond à votre usage.
  • Clusterisez sur l’identifiant d’entité, comme user_id ou order_id.
  • Filtrez la période analysée avant d’appliquer les fonctions de fenêtre.
  • Sélectionnez uniquement les colonnes nécessaires.
  • Testez la logique sur un échantillon avant de la généraliser.

Exemple métier complet: délai entre ouverture et fermeture d’un ticket

Imaginons une table de support client avec les colonnes ticket_id, status et status_ts. Vous souhaitez calculer le nombre d’heures entre le statut “opened” et le statut “closed”. Ici, un self join est souvent adapté, surtout si vous avez besoin de comparer deux états précis.

WITH opened AS ( SELECT ticket_id, status_ts AS opened_ts FROM project.dataset.ticket_history WHERE status = ‘opened’ ), closed AS ( SELECT ticket_id, status_ts AS closed_ts FROM project.dataset.ticket_history WHERE status = ‘closed’ ) SELECT o.ticket_id, o.opened_ts, c.closed_ts, TIMESTAMP_DIFF(c.closed_ts, o.opened_ts, HOUR) AS resolution_hours FROM opened o JOIN closed c ON o.ticket_id = c.ticket_id WHERE c.closed_ts >= o.opened_ts;

Dans un environnement réel, vous ajouteriez souvent une logique pour sélectionner la première fermeture valide, gérer les réouvertures et exclure les tickets incomplets. Le point important est que BigQuery vous offre plusieurs modèles de calcul, et que le meilleur dépend davantage du workflow que de la fonction elle-même.

En résumé

Pour réussir un calcul de temps entre deux timestamps stockés sur deux lignes dans BigQuery, il faut raisonner en deux étapes. D’abord, apparier correctement les lignes grâce à LAG(), LEAD() ou un self join. Ensuite, appliquer TIMESTAMP_DIFF avec l’unité qui correspond à votre cas d’usage. Si vos données sont bien partitionnées, bien ordonnées et stockées dans le bon type temporel, vous obtiendrez des métriques fiables, exploitables et faciles à industrialiser.

Le calculateur ci-dessus vous aide à valider la logique métier avant d’écrire la requête finale. C’est particulièrement utile pour vérifier le sens du calcul, le choix d’unité et la structure SQL que vous devrez reproduire dans votre entrepôt de données.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top