Passer au contenu principal
La clause ORDER BY contient :
  • une liste d’expressions, par exemple ORDER BY visits, search_phrase,
  • une liste de nombres faisant référence aux colonnes de la clause SELECT, par exemple ORDER BY 2, 1, ou
  • ALL, qui désigne toutes les colonnes de la clause SELECT, par exemple ORDER BY ALL.
Pour désactiver le tri par numéros de colonnes, définissez le paramètre enable_positional_arguments = 0. Pour désactiver le tri par ALL, définissez le paramètre enable_order_by_all = 0. La clause ORDER BY peut être accompagnée du modificateur DESC (décroissant) ou ASC (croissant), qui détermine le sens du tri. Sauf si un ordre de tri explicite est indiqué, ASC est utilisé par défaut. Le sens du tri s’applique à une seule expression, et non à toute la liste, par exemple ORDER BY Visits DESC, SearchPhrase. De plus, le tri respecte la casse. Les lignes ayant des valeurs identiques pour des expressions de tri sont renvoyées dans un ordre arbitraire et non déterministe. Si la clause ORDER BY est omise dans une instruction SELECT, l’ordre des lignes est également arbitraire et non déterministe.

Tri des valeurs spéciales

Il existe deux façons de trier NaN et NULL :
  • Par défaut ou avec le modificateur NULLS LAST : d’abord les valeurs, puis NaN, puis NULL.
  • Avec le modificateur NULLS FIRST : d’abord NULL, puis NaN, puis les autres valeurs.

Exemple

Pour la table suivante
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 2 │    2 │
│ 1 │  nan │
│ 2 │    2 │
│ 3 │    4 │
│ 5 │    6 │
│ 6 │  nan │
│ 7 │ ᴺᵁᴸᴸ │
│ 6 │    7 │
│ 8 │    9 │
└───┴──────┘
Exécutez la requête SELECT * FROM t_null_nan ORDER BY y NULLS FIRST pour obtenir :
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 7 │ ᴺᵁᴸᴸ │
│ 1 │  nan │
│ 6 │  nan │
│ 2 │    2 │
│ 2 │    2 │
│ 3 │    4 │
│ 5 │    6 │
│ 6 │    7 │
│ 8 │    9 │
└───┴──────┘
Lorsque des nombres à virgule flottante sont triés, les NaN sont distincts des autres valeurs. Quel que soit l’ordre de tri, les NaN se trouvent à la fin. Autrement dit, pour un tri croissant, ils sont placés comme s’ils étaient supérieurs à tous les autres nombres, tandis que pour un tri décroissant, ils sont placés comme s’ils étaient inférieurs aux autres.

Prise en charge de la collation

Pour trier des valeurs String, vous pouvez spécifier une collation (règle de comparaison). Exemple : ORDER BY SearchPhrase COLLATE 'tr' - pour trier par mot-clé par ordre croissant, en utilisant l’alphabet turc, sans tenir compte de la casse, en supposant que les chaînes sont encodées en UTF-8. COLLATE peut être spécifié, ou non, indépendamment pour chaque expression dans ORDER BY. Si ASC ou DESC est spécifié, COLLATE se place après. Lorsque COLLATE est utilisé, le tri est toujours insensible à la casse. La collation est prise en charge avec LowCardinality, Nullable, Array et Tuple. Nous recommandons d’utiliser COLLATE uniquement pour le tri final d’un petit nombre de lignes, car le tri avec COLLATE est moins efficace qu’un tri normal par octets.

Exemples de collation

Exemple avec uniquement des valeurs String : Table d’entrée :
┌─x─┬─s────┐
│ 1 │ bca  │
│ 2 │ ABC  │
│ 3 │ 123a │
│ 4 │ abc  │
│ 5 │ BCA  │
└───┴──────┘
Query
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Response
┌─x─┬─s────┐
│ 3 │ 123a │
│ 4 │ abc  │
│ 2 │ ABC  │
│ 1 │ bca  │
│ 5 │ BCA  │
└───┴──────┘
Exemple avec Nullable : Table d’entrée :
┌─x─┬─s────┐
│ 1 │ bca  │
│ 2 │ ᴺᵁᴸᴸ │
│ 3 │ ABC  │
│ 4 │ 123a │
│ 5 │ abc  │
│ 6 │ ᴺᵁᴸᴸ │
│ 7 │ BCA  │
└───┴──────┘
Query
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Response
┌─x─┬─s────┐
│ 4 │ 123a │
│ 5 │ abc  │
│ 3 │ ABC  │
│ 1 │ bca  │
│ 7 │ BCA  │
│ 6 │ ᴺᵁᴸᴸ │
│ 2 │ ᴺᵁᴸᴸ │
└───┴──────┘
Exemple avec Array : Table d’entrée :
┌─x─┬─s─────────────┐
│ 1 │ ['Z']         │
│ 2 │ ['z']         │
│ 3 │ ['a']         │
│ 4 │ ['A']         │
│ 5 │ ['z','a']     │
│ 6 │ ['z','a','a'] │
│ 7 │ ['']          │
└───┴───────────────┘
Query
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Response
┌─x─┬─s─────────────┐
│ 7 │ ['']          │
│ 3 │ ['a']         │
│ 4 │ ['A']         │
│ 2 │ ['z']         │
│ 5 │ ['z','a']     │
│ 6 │ ['z','a','a'] │
│ 1 │ ['Z']         │
└───┴───────────────┘
Exemple avec une chaîne LowCardinality : Table d’entrée :
┌─x─┬─s───┐
│ 1 │ Z   │
│ 2 │ z   │
│ 3 │ a   │
│ 4 │ A   │
│ 5 │ za  │
│ 6 │ zaa │
│ 7 │     │
└───┴─────┘
Query
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Response
┌─x─┬─s───┐
│ 7 │     │
│ 3 │ a   │
│ 4 │ A   │
│ 2 │ z   │
│ 1 │ Z   │
│ 5 │ za  │
│ 6 │ zaa │
└───┴─────┘
Exemple avec Tuple :
Response
┌─x─┬─s───────┐
│ 1 │ (1,'Z') │
│ 2 │ (1,'z') │
│ 3 │ (1,'a') │
│ 4 │ (2,'z') │
│ 5 │ (1,'A') │
│ 6 │ (2,'Z') │
│ 7 │ (2,'A') │
└───┴─────────┘
Query
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Response
┌─x─┬─s───────┐
│ 3 │ (1,'a') │
│ 5 │ (1,'A') │
│ 2 │ (1,'z') │
│ 1 │ (1,'Z') │
│ 7 │ (2,'A') │
│ 4 │ (2,'z') │
│ 6 │ (2,'Z') │
└───┴─────────┘

Détails d’implémentation

Moins de RAM est utilisée si un LIMIT suffisamment faible est spécifié en plus de ORDER BY. Sinon, la quantité de mémoire consommée est proportionnelle au volume de données à trier. Dans le cadre du traitement distribué des requêtes, si GROUP BY est omis, le tri est effectué en partie sur les serveurs distants, puis les résultats sont fusionnés sur le serveur demandeur. Cela signifie que, pour un tri distribué, le volume de données à trier peut être supérieur à la quantité de mémoire disponible sur un seul serveur. S’il n’y a pas assez de RAM, il est possible d’effectuer le tri en mémoire externe (en créant des fichiers temporaires sur un disque). Utilisez le paramètre max_bytes_before_external_sort à cette fin. S’il est défini sur 0 (valeur par défaut), le tri externe est désactivé. S’il est activé, lorsque le volume de données à trier atteint le nombre d’octets spécifié, les données collectées sont triées puis écrites dans un fichier temporaire. Une fois toutes les données lues, tous les fichiers triés sont fusionnés et les résultats sont renvoyés. Les fichiers sont écrits dans le répertoire /var/lib/clickhouse/tmp/ défini dans la config (par défaut, mais vous pouvez utiliser le paramètre tmp_path pour modifier ce réglage). Vous pouvez également n’utiliser l’écriture sur disque que si la requête dépasse les limites de mémoire. Par exemple, max_bytes_ratio_before_external_sort=0.6 n’activera l’écriture sur disque que lorsque la requête atteindra 60% de la limite de mémoire (utilisateur/serveur). L’exécution d’une requête peut utiliser plus de mémoire que max_bytes_before_external_sort. C’est pourquoi ce paramètre doit avoir une valeur nettement inférieure à max_memory_usage. Par exemple, si votre serveur dispose de 128 Go de RAM et que vous devez exécuter une seule requête, définissez max_memory_usage sur 100 Go et max_bytes_before_external_sort sur 80 Go. Le tri externe est beaucoup moins efficace que le tri en RAM.

Optimisation de la lecture des données

Si l’expression ORDER BY a un préfixe qui correspond à la clé de tri de la table, vous pouvez optimiser la requête à l’aide du paramètre optimize_read_in_order. Lorsque le paramètre optimize_read_in_order est activé, le serveur ClickHouse utilise l’index de la table et lit les données dans l’ordre de la clé ORDER BY. Cela permet d’éviter de lire toutes les données lorsqu’une clause LIMIT est spécifiée. Les requêtes sur de gros volumes de données avec une petite limite sont donc traitées plus rapidement. L’optimisation fonctionne avec ASC comme avec DESC, mais elle ne fonctionne pas avec la clause GROUP BY ni avec le modificateur FINAL. Lorsque le paramètre optimize_read_in_order est désactivé, le serveur ClickHouse n’utilise pas l’index de la table lors du traitement des requêtes SELECT. Envisagez de désactiver manuellement optimize_read_in_order lorsque vous exécutez des requêtes comportant une clause ORDER BY, un LIMIT élevé et une condition WHERE qui oblige à lire un très grand nombre d’enregistrements avant de trouver les données recherchées. L’optimisation est prise en charge par les moteurs de table suivants : Dans les tables utilisant le moteur MaterializedView, l’optimisation fonctionne avec des vues telles que SELECT ... FROM merge_tree_table ORDER BY pk. En revanche, elle n’est pas prise en charge pour des requêtes comme SELECT ... FROM view ORDER BY pk si la requête de la vue ne comporte pas de clause ORDER BY.

Modificateur ORDER BY Expr WITH FILL

Ce modificateur peut également être combiné avec le modificateur LIMIT … WITH TIES. Le modificateur WITH FILL peut être utilisé après ORDER BY expr, avec les paramètres facultatifs FROM expr, TO expr et STEP expr. Toutes les valeurs manquantes de la colonne expr seront générées séquentiellement, et les autres colonnes prendront leurs valeurs par défaut. Pour remplir plusieurs colonnes, ajoutez le modificateur WITH FILL avec ses paramètres facultatifs après chaque nom de colonne dans la section ORDER BY.
Query
ORDER BY expr [WITH FILL] [FROM const_expr] [TO const_expr] [STEP const_numeric_expr] [STALENESS const_numeric_expr], ... exprN [WITH FILL] [FROM expr] [TO expr] [STEP numeric_expr] [STALENESS numeric_expr]
[INTERPOLATE [(col [AS expr], ... colN [AS exprN])]]
WITH FILL peut être appliqué à des champs de type Numeric (tous les types float, decimal et int) ou Date/DateTime. Lorsqu’il est appliqué à des champs String, les valeurs manquantes sont remplacées par des chaînes vides. Lorsque FROM const_expr n’est pas défini, la séquence de remplissage utilise la valeur minimale du champ expr de ORDER BY. Lorsque TO const_expr n’est pas défini, la séquence de remplissage utilise la valeur maximale du champ expr de ORDER BY. Lorsque STEP const_numeric_expr est défini, const_numeric_expr est interprété tel quel pour les types numériques, comme des jours pour le type Date et comme des secondes pour le type DateTime. Il prend également en charge le type de données INTERVAL, qui représente des intervalles de temps et de date. Lorsque STEP const_numeric_expr est omis, la séquence de remplissage utilise 1.0 pour le type numérique, 1 day pour le type Date et 1 second pour le type DateTime. Lorsque STALENESS const_numeric_expr est défini, la requête génère des lignes jusqu’à ce que la différence par rapport à la ligne précédente dans les données d’origine dépasse const_numeric_expr. INTERPOLATE peut être appliqué aux colonnes qui ne participent pas à ORDER BY WITH FILL. Ces colonnes sont remplies en fonction des valeurs des champs précédents en appliquant expr. Si expr n’est pas présent, la valeur précédente est répétée. Si la liste est omise, toutes les colonnes autorisées sont incluses. Exemple de requête sans WITH FILL :
Query
SELECT n, source FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n;
Response
┌─n─┬─source───┐
│ 1 │ original │
│ 4 │ original │
│ 7 │ original │
└───┴──────────┘
Même requête après avoir appliqué le modificateur WITH FILL :
Query
SELECT n, source FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;
Response
┌───n─┬─source───┐
│   0 │          │
│ 0.5 │          │
│   1 │ original │
│ 1.5 │          │
│   2 │          │
│ 2.5 │          │
│   3 │          │
│ 3.5 │          │
│   4 │ original │
│ 4.5 │          │
│   5 │          │
│ 5.5 │          │
│   7 │ original │
└─────┴──────────┘
Dans le cas de plusieurs champs ORDER BY field2 WITH FILL, field1 WITH FILL, l’ordre du remplissage suit celui des champs dans la clause ORDER BY. Exemple :
Query
SELECT
    toDate((number * 10) * 86400) AS d1,
    toDate(number * 86400) AS d2,
    'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
    d2 WITH FILL,
    d1 WITH FILL STEP 5;
Response
┌───d1───────┬───d2───────┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-01 │ 1970-01-03 │          │
│ 1970-01-01 │ 1970-01-04 │          │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-01-01 │ 1970-01-06 │          │
│ 1970-01-01 │ 1970-01-07 │          │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
Le champ d1 n’est pas complété avec la valeur par défaut, car nous n’avons pas de valeurs répétées pour d2 et la séquence de d1 ne peut pas être calculée correctement. La requête suivante, avec le champ modifié dans ORDER BY :
Query
SELECT
    toDate((number * 10) * 86400) AS d1,
    toDate(number * 86400) AS d2,
    'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
    d1 WITH FILL STEP 5,
    d2 WITH FILL;
Response
┌───d1───────┬───d2───────┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-16 │ 1970-01-01 │          │
│ 1970-01-21 │ 1970-01-01 │          │
│ 1970-01-26 │ 1970-01-01 │          │
│ 1970-01-31 │ 1970-01-01 │          │
│ 1970-02-05 │ 1970-01-01 │          │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-02-15 │ 1970-01-01 │          │
│ 1970-02-20 │ 1970-01-01 │          │
│ 1970-02-25 │ 1970-01-01 │          │
│ 1970-03-02 │ 1970-01-01 │          │
│ 1970-03-07 │ 1970-01-01 │          │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
La requête suivante utilise le type de données INTERVAL d’un jour pour chaque valeur remplie dans la colonne d1 :
Query
SELECT
    toDate((number * 10) * 86400) AS d1,
    toDate(number * 86400) AS d2,
    'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
    d1 WITH FILL STEP INTERVAL 1 DAY,
    d2 WITH FILL;
Response
┌─────────d1─┬─────────d2─┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-12 │ 1970-01-01 │          │
│ 1970-01-13 │ 1970-01-01 │          │
│ 1970-01-14 │ 1970-01-01 │          │
│ 1970-01-15 │ 1970-01-01 │          │
│ 1970-01-16 │ 1970-01-01 │          │
│ 1970-01-17 │ 1970-01-01 │          │
│ 1970-01-18 │ 1970-01-01 │          │
│ 1970-01-19 │ 1970-01-01 │          │
│ 1970-01-20 │ 1970-01-01 │          │
│ 1970-01-21 │ 1970-01-01 │          │
│ 1970-01-22 │ 1970-01-01 │          │
│ 1970-01-23 │ 1970-01-01 │          │
│ 1970-01-24 │ 1970-01-01 │          │
│ 1970-01-25 │ 1970-01-01 │          │
│ 1970-01-26 │ 1970-01-01 │          │
│ 1970-01-27 │ 1970-01-01 │          │
│ 1970-01-28 │ 1970-01-01 │          │
│ 1970-01-29 │ 1970-01-01 │          │
│ 1970-01-30 │ 1970-01-01 │          │
│ 1970-01-31 │ 1970-01-01 │          │
│ 1970-02-01 │ 1970-01-01 │          │
│ 1970-02-02 │ 1970-01-01 │          │
│ 1970-02-03 │ 1970-01-01 │          │
│ 1970-02-04 │ 1970-01-01 │          │
│ 1970-02-05 │ 1970-01-01 │          │
│ 1970-02-06 │ 1970-01-01 │          │
│ 1970-02-07 │ 1970-01-01 │          │
│ 1970-02-08 │ 1970-01-01 │          │
│ 1970-02-09 │ 1970-01-01 │          │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-02-11 │ 1970-01-01 │          │
│ 1970-02-12 │ 1970-01-01 │          │
│ 1970-02-13 │ 1970-01-01 │          │
│ 1970-02-14 │ 1970-01-01 │          │
│ 1970-02-15 │ 1970-01-01 │          │
│ 1970-02-16 │ 1970-01-01 │          │
│ 1970-02-17 │ 1970-01-01 │          │
│ 1970-02-18 │ 1970-01-01 │          │
│ 1970-02-19 │ 1970-01-01 │          │
│ 1970-02-20 │ 1970-01-01 │          │
│ 1970-02-21 │ 1970-01-01 │          │
│ 1970-02-22 │ 1970-01-01 │          │
│ 1970-02-23 │ 1970-01-01 │          │
│ 1970-02-24 │ 1970-01-01 │          │
│ 1970-02-25 │ 1970-01-01 │          │
│ 1970-02-26 │ 1970-01-01 │          │
│ 1970-02-27 │ 1970-01-01 │          │
│ 1970-02-28 │ 1970-01-01 │          │
│ 1970-03-01 │ 1970-01-01 │          │
│ 1970-03-02 │ 1970-01-01 │          │
│ 1970-03-03 │ 1970-01-01 │          │
│ 1970-03-04 │ 1970-01-01 │          │
│ 1970-03-05 │ 1970-01-01 │          │
│ 1970-03-06 │ 1970-01-01 │          │
│ 1970-03-07 │ 1970-01-01 │          │
│ 1970-03-08 │ 1970-01-01 │          │
│ 1970-03-09 │ 1970-01-01 │          │
│ 1970-03-10 │ 1970-01-01 │          │
│ 1970-03-11 │ 1970-01-01 │          │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
Exemple de requête sans STALENESS :
Query
SELECT number AS key, 5 * number value, 'original' AS source
FROM numbers(16) WHERE key % 5 == 0
ORDER BY key WITH FILL;
Response
    ┌─key─┬─value─┬─source───┐
 1. │   0 │     0 │ original │
 2. │   1 │     0 │          │
 3. │   2 │     0 │          │
 4. │   3 │     0 │          │
 5. │   4 │     0 │          │
 6. │   5 │    25 │ original │
 7. │   6 │     0 │          │
 8. │   7 │     0 │          │
 9. │   8 │     0 │          │
10. │   9 │     0 │          │
11. │  10 │    50 │ original │
12. │  11 │     0 │          │
13. │  12 │     0 │          │
14. │  13 │     0 │          │
15. │  14 │     0 │          │
16. │  15 │    75 │ original │
    └─────┴───────┴──────────┘
Même requête après avoir appliqué STALENESS 3 :
Query
SELECT number AS key, 5 * number value, 'original' AS source
FROM numbers(16) WHERE key % 5 == 0
ORDER BY key WITH FILL STALENESS 3;
Response
    ┌─key─┬─value─┬─source───┐
 1. │   0 │     0 │ original │
 2. │   1 │     0 │          │
 3. │   2 │     0 │          │
 4. │   5 │    25 │ original │
 5. │   6 │     0 │          │
 6. │   7 │     0 │          │
 7. │  10 │    50 │ original │
 8. │  11 │     0 │          │
 9. │  12 │     0 │          │
10. │  15 │    75 │ original │
11. │  16 │     0 │          │
12. │  17 │     0 │          │
    └─────┴───────┴──────────┘
Exemple de requête sans INTERPOLATE :
Query
SELECT n, source, inter FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;
Response
┌───n─┬─source───┬─inter─┐
│   0 │          │     0 │
│ 0.5 │          │     0 │
│   1 │ original │     1 │
│ 1.5 │          │     0 │
│   2 │          │     0 │
│ 2.5 │          │     0 │
│   3 │          │     0 │
│ 3.5 │          │     0 │
│   4 │ original │     4 │
│ 4.5 │          │     0 │
│   5 │          │     0 │
│ 5.5 │          │     0 │
│   7 │ original │     7 │
└─────┴──────────┴───────┘
Même requête après avoir appliqué INTERPOLATE :
Query
SELECT n, source, inter FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1);
Response
┌───n─┬─source───┬─inter─┐
│   0 │          │     0 │
│ 0.5 │          │     0 │
│   1 │ original │     1 │
│ 1.5 │          │     2 │
│   2 │          │     3 │
│ 2.5 │          │     4 │
│   3 │          │     5 │
│ 3.5 │          │     6 │
│   4 │ original │     4 │
│ 4.5 │          │     5 │
│   5 │          │     6 │
│ 5.5 │          │     7 │
│   7 │ original │     7 │
└─────┴──────────┴───────┘

Remplissage regroupé par préfixe de tri

Il peut être utile de remplir indépendamment les lignes qui ont les mêmes valeurs dans certaines colonnes ; un bon exemple est le remplissage des valeurs manquantes dans les séries temporelles. Supposons qu’il existe la table de séries temporelles suivante :
CREATE TABLE timeseries
(
    `sensor_id` UInt64,
    `timestamp` DateTime64(3, 'UTC'),
    `value` Float64
)
ENGINE = Memory;

SELECT * FROM timeseries;

┌─sensor_id─┬───────────────timestamp─┬─value─┐
2342021-12-01 00:00:03.0003
4322021-12-01 00:00:01.0001
2342021-12-01 00:00:07.0007
4322021-12-01 00:00:05.0005
└───────────┴─────────────────────────┴───────┘
Et nous aimerions remplir les valeurs manquantes pour chaque capteur indépendamment, avec un intervalle d’une seconde. Pour ce faire, utilisez la colonne sensor_id comme préfixe de tri pour remplir la colonne timestamp :
SELECT *
FROM timeseries
ORDER BY
    sensor_id,
    timestamp WITH FILL
INTERPOLATE ( value AS 9999 )

┌─sensor_id─┬───────────────timestamp─┬─value─┐
2342021-12-01 00:00:03.0003
2342021-12-01 00:00:04.0009999
2342021-12-01 00:00:05.0009999
2342021-12-01 00:00:06.0009999
2342021-12-01 00:00:07.0007
4322021-12-01 00:00:01.0001
4322021-12-01 00:00:02.0009999
4322021-12-01 00:00:03.0009999
4322021-12-01 00:00:04.0009999
4322021-12-01 00:00:05.0005
└───────────┴─────────────────────────┴───────┘
Ici, la colonne value a été interpolée avec 9999 simplement pour rendre les lignes ajoutées plus visibles. Ce comportement est contrôlé par le paramètre use_with_fill_by_sorting_prefix (activé par défaut)
Dernière modification le 25 juin 2026