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:
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.
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.
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.
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
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
- Si vous comparez chaque événement au précédent: utilisez LAG().
- Si vous comparez chaque événement au suivant: utilisez LEAD().
- Si vous comparez deux types d’événements spécifiques: utilisez un self join ou une logique d’appariement plus fine.
- Si vos données sont internationales: standardisez en TIMESTAMP UTC.
- 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.
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.