Dans ce guide, vous apprendrez à utiliser les tableaux dans ClickHouse, ainsi que quelques-unes des fonctions de tableau les plus couramment utilisées.
Introduction aux tableaux
array :
[] :
Création de tableaux de types différents
Création de tableaux de types différents
Vous pouvez utiliser le paramètre Vous pouvez ensuite extraire du tableau les valeurs par nom de type :
use_variant_as_common_type pour modifier le comportement par défaut décrit ci-dessus.
Cela permet d’utiliser le type Variant comme type de résultat pour les fonctions if/multiIf/array/map lorsqu’il n’existe aucun type commun entre les types d’argument.Par exemple :[] offre un moyen pratique d’accéder aux éléments d’un tableau.
Dans ClickHouse, il est important de savoir que l’indice d’un tableau commence toujours à 1.
Cela peut différer d’autres langages de programmation auxquels vous êtes habitué, où les tableaux sont indexés à partir de zéro.
Par exemple, étant donné un tableau, vous pouvez en sélectionner le premier élément en écrivant :
Fonctions de tableau
fonctions length, arrayEnumerate, indexOf, has*
length renvoie le nombre d’éléments du tableau :
arrayEnumerate pour retourner un tableau contenant les indices des éléments :
indexOf :
indexOfAssumeSorted.
Les fonctions has, hasAll et hasAny sont utiles pour déterminer si un tableau contient une valeur donnée.
Prenons l’exemple suivant :
Exploration des données de vol avec les fonctions de tableau
groupArray
groupArray, qui prend les valeurs de la colonne spécifiée pour chaque ligne et les regroupe dans un tableau.
Exécutez la requête ci-dessous pour voir comment cela fonctionne :
La fonction toStringCutToZero dans la requête ci-dessus sert à supprimer les caractères nuls qui apparaissent après le code à 3 lettres de certains aéroports.
Avec les données sous cette forme, nous pouvons facilement classer les aéroports les plus fréquentés en calculant la longueur des tableaux « Destinations » agrégés :
arrayMap et arrayZip
arrayMap en est un exemple : elle renvoie un nouveau tableau à partir du tableau fourni en appliquant une fonction lambda à chaque élément du tableau d’origine.
Exécutez la requête ci-dessous, qui utilise la fonction arrayMap, pour voir quels vols étaient retardés ou à l’heure.
Pour chaque paire origine/destination, elle affiche le numéro de queue et le statut de chaque vol :
Dans la requête ci-dessus, la fonction arrayMap prend un tableau à un seul élément [DepDelayMinutes] et applique la fonction lambda d -> if(d >= 30, 'DELAYED', if(d >= 15, 'WARNING', 'ON-TIME' pour le catégoriser.
Ensuite, le premier élément du tableau résultant est extrait avec [DepDelayMinutes][1].
La fonction arrayZip combine le tableau Tail_Number et le tableau statuses en un seul tableau.
arrayFilter
DEN, ATL et DFW :
Dans la requête ci-dessus, nous passons une fonction lambda comme premier argument à la fonction arrayFilter.
Cette fonction lambda prend elle-même le retard en minutes (d) et renvoie 1 si la condition est remplie, sinon 0.
arraySort et arrayIntersect
arraySort et arrayIntersect.
arraySort prend un tableau et trie ses éléments par défaut dans l’ordre croissant, même s’il est également possible de lui passer une fonction lambda pour définir l’ordre de tri.
arrayIntersect prend plusieurs tableaux et renvoie un tableau contenant les éléments présents dans tous les tableaux.
Exécutez la requête ci-dessous pour voir ces deux fonctions de tableau en action :
La requête fonctionne en deux grandes étapes.
D’abord, elle crée un jeu de données temporaire appelé airport_routes à l’aide d’une expression de table commune (CTE), qui examine tous les vols du 1er janvier 2024 et construit, pour chaque aéroport d’origine, une liste triée de toutes les destinations uniques qu’il dessert.
Dans le jeu de résultats airport_routes, par exemple, DEN peut avoir un tableau contenant toutes les villes qu’il dessert, comme ['ATL', 'BOS', 'LAX', 'MIA', ...], et ainsi de suite.
Dans la deuxième étape, la requête prend cinq grands hubs aéroportuaires américains (DEN, ATL, DFW, ORD et LAS) et compare toutes les paires possibles.
Elle le fait à l’aide d’un CROSS JOIN, qui crée toutes les combinaisons de ces aéroports.
Ensuite, pour chaque paire, elle utilise la fonction arrayIntersect pour identifier les destinations qui apparaissent dans les listes des deux aéroports.
La fonction length compte le nombre de destinations qu’ils ont en commun.
La condition a1.Origin < a2.Origin garantit que chaque paire n’apparaît qu’une seule fois.
Sans cela, vous obtiendriez à la fois JFK-LAX et LAX-JFK comme résultats distincts, ce qui serait redondant puisqu’ils représentent la même comparaison.
Enfin, la requête trie les résultats pour montrer quelles paires d’aéroports ont le plus grand nombre de destinations communes et ne renvoie que les 10 premières.
Cela met en évidence les grands hubs dont les réseaux de liaisons se recoupent le plus, ce qui peut indiquer des marchés concurrentiels où plusieurs compagnies aériennes desservent les mêmes paires de villes, ou des hubs qui desservent des régions géographiques similaires et pourraient donc servir de points de correspondance alternatifs pour les voyageurs.
arrayReduce
arrayReduce, pour trouver le retard moyen et le retard maximal
pour chaque itinéraire au départ de l’aéroport international de Denver :
Dans l’exemple ci-dessus, nous avons utilisé arrayReduce pour déterminer les retards moyen et maximal de différents vols au départ de DEN.
arrayReduce applique une fonction d’agrégation, spécifiée dans le premier paramètre de la fonction, aux éléments du tableau fourni, spécifié dans le second paramètre de la fonction.
arrayJoin
arrayJoin.
arrayJoin « déplie » un tableau en créant une ligne distincte pour chaque élément.
Cela s’apparente aux fonctions SQL UNNEST ou EXPLODE dans d’autres bases de données.
Contrairement à la plupart des fonctions de tableau, qui renvoient des tableaux ou des valeurs scalaires, arrayJoin modifie fondamentalement le jeu de résultats en multipliant le nombre de lignes.
Considérez la requête ci-dessous, qui renvoie un tableau de valeurs de 0 à 100 par pas de 10.
On peut considérer que ce tableau représente différents temps de retard : 0 minute, 10 minutes, 20 minutes, etc.
Nous pouvons écrire une requête utilisant arrayJoin pour déterminer combien de retards il y a eu jusqu’à ce nombre de minutes entre deux aéroports.
La requête ci-dessous crée un histogramme montrant la distribution des retards de vol de Denver (DEN) à Miami (MIA) le 1er janvier 2024, en utilisant des buckets de retard cumulatifs :
Dans la requête ci-dessus, nous renvoyons un tableau de retards à l’aide d’une clause CTE (clause WITH).
Destination convertit le code de destination en chaîne de caractères.
Nous utilisons arrayJoin pour déplier le tableau de retards en lignes distinctes.
Chaque valeur du tableau delay devient sa propre ligne avec l’alias del,
et nous obtenons 10 lignes : une pour del=0, une pour del=10, une pour del=20, etc.
Pour chaque seuil de retard (del), la requête compte combien de vols avaient des retards supérieurs ou égaux à ce seuil
à l’aide de countIf(DepDelayMinutes >= del).
arrayJoin a également un équivalent en SQL : ARRAY JOIN.
La requête ci-dessus est reproduite ci-dessous avec l’équivalent SQL à des fins de comparaison :
Étapes suivantes
groupArray, arrayFilter, arrayMap, arrayReduce et arrayJoin.
Pour aller plus loin, consultez la référence complète des fonctions de tableau afin de découvrir d’autres fonctions comme arrayFlatten, arrayReverse et arrayDistinct.
Vous pouvez également vous intéresser à des structures de données connexes, comme les tuples et les types JSON et Map, qui s’utilisent très bien avec les tableaux.
Exercez-vous à appliquer ces concepts à vos propres jeux de données, et testez différentes requêtes dans le SQL playground ou sur d’autres jeux de données d’exemple.
Les tableaux sont une fonctionnalité fondamentale de ClickHouse qui permettent d’effectuer des requêtes analytiques efficaces. À mesure que vous vous familiariserez avec les fonctions de tableau, vous constaterez qu’elles peuvent considérablement simplifier des aggregations complexes et l’analyse de séries temporelles.
Pour aller encore plus loin sur les tableaux, nous vous recommandons la vidéo YouTube ci-dessous de Mark, notre expert data :