Expressions de table communes
SELECT où une expression de table est autorisée.
Les sous-requêtes nommées peuvent être référencées par leur nom dans la portée de la requête courante ou dans les portées des sous-requêtes enfants.
Chaque référence à une expression de table commune dans une requête SELECT est toujours remplacée par la sous-requête de sa définition si la CTE n’est pas explicitement définie comme matérialisée (voir Expressions de table communes matérialisées).
La récursivité est évitée en masquant la CTE courante du processus de résolution des identifiants.
Veuillez noter que les CTE ne garantissent pas les mêmes résultats partout où elles sont appelées, car la requête est réexécutée à chaque utilisation.
Syntaxe
Exemple
1000000
Cependant, comme nous faisons référence deux fois à cte_numbers, des nombres aléatoires sont générés à chaque fois et nous obtenons donc des résultats aléatoires différents : 280501, 392454, 261636, 196227, etc.
Expressions de table communes matérialisées
MATERIALIZED indique à ClickHouse d’exécuter la sous-requête de la CTE exactement une fois, de stocker les résultats dans une table temporaire, puis d’utiliser cette table pour toutes les références.
Cela est particulièrement utile lorsque la même CTE est référencée plusieurs fois dans une requête (par exemple, dans des auto-jointures ou plusieurs sous-requêtes IN), car le calcul sous-jacent n’est effectué qu’une seule fois.
Les CTE matérialisées sont une fonctionnalité expérimentale.
Elles nécessitent que l’analyseur et le paramètre
enable_materialized_cte soient activés.Syntaxe
Quand utiliser
- La même CTE est référencée plus d’une fois dans une requête.
Sans
MATERIALIZED, chaque référence réexécute la sous-requête de manière indépendante. - La CTE contient des fonctions non déterministes comme
generateRandom. La matérialisation garantit que toutes les références voient les mêmes données. - La CTE implique des calculs coûteux (agrégations, jointures, lecture de grands volumes de données) qu’il ne faut pas répéter.
Exemples
MATERIALIZED, les deux côtés de la jointure exécuteraient la sous-requête indépendamment.
Avec MATERIALIZED, la table n’est parcourue qu’une seule fois et les deux côtés de la jointure lisent dans la même table temporaire.
generateRandom produisent des résultats différents à chaque référence.
La matérialisation de la CTE garantit la cohérence :
1000000.
Exemple 3 : Chaînage de CTE matérialisées
Les CTE matérialisées peuvent faire référence à d’autres CTE matérialisées.
ClickHouse résout les dépendances et les matérialise dans le bon ordre :
Restrictions
- Paramètre expérimental requis : le paramètre
enable_materialized_ctedoit être activé. - Analyseur requis : les CTE matérialisées fonctionnent uniquement lorsque l’analyseur est activé (
enable_analyzer = 1). - Non pris en charge avec
RECURSIVE: la combinaison des mots-clésMATERIALIZEDetRECURSIVEn’est pas autorisée et entraîne une exceptionUNSUPPORTED_METHOD. - Les CTE corrélées sont interdites : une CTE matérialisée ne peut pas référencer des colonnes provenant de portées de requête englobantes.
Expressions scalaires communes
WITH.
Les expressions scalaires communes peuvent être référencées n’importe où dans la requête.
Si une expression scalaire commune fait référence à autre chose qu’un littéral constant, elle peut entraîner la présence de variables libres.
ClickHouse résout chaque identifiant dans la portée la plus proche possible, ce qui signifie que des variables libres peuvent faire référence à des entités inattendues en cas de conflit de noms, ou conduire à une sous-requête corrélée.
Il est recommandé de définir une CSE sous forme de fonction lambda (possible uniquement lorsque l’analyseur est activé), en liant tous les identifiants utilisés afin d’obtenir un comportement plus prévisible lors de la résolution des identifiants d’expression.
Syntaxe
Exemples
extension n’est pas liée dans le corps de la fonction lambda gen_name.
Bien que extension soit définie comme '.txt' en tant qu’expression scalaire commune dans la portée de définition et d’utilisation de generated_names, elle est résolue comme une colonne de la table extension_list, car elle est disponible dans la sous-requête generated_names.
Requêtes récursives
RECURSIVE, facultatif, permet à une requête WITH de faire référence à son propre résultat. Exemple :
Exemple : Additionner les entiers de 1 à 100
Les CTE récursifs s’appuient sur l’analyseur de requêtes, introduit dans la version
24.3. Si vous utilisez la version 24.3+ et rencontrez une exception (UNKNOWN_TABLE) ou (UNSUPPORTED_METHOD), cela indique que l’analyseur est désactivé sur votre instance, votre rôle ou votre profil. Pour activer l’analyseur, activez le paramètre allow_experimental_analyzer ou mettez à jour le paramètre compatibility vers une version plus récente.
À partir de la version 24.8, l’analyseur est pleinement passé en production, et le paramètre allow_experimental_analyzer a été renommé en enable_analyzer.WITH est toujours la suivante : un terme non récursif, puis UNION ALL, puis un terme récursif, seul ce dernier pouvant contenir une référence à la propre sortie de la requête. Une requête CTE récursive s’exécute comme suit :
- Évaluez le terme non récursif. Placez le résultat de cette requête dans une table de travail temporaire.
- Tant que la table de travail n’est pas vide, répétez ces étapes :
- Évaluez le terme récursif en remplaçant l’auto-référence récursive par le contenu actuel de la table de travail. Placez le résultat de cette requête dans une table intermédiaire temporaire.
- Remplacez le contenu de la table de travail par celui de la table intermédiaire, puis videz la table intermédiaire.
Ordre de parcours
Détection des cycles
Maximum recursive CTE evaluation depth :
Requêtes infinies
LIMIT est utilisé dans la requête externe :
Exemple : Requête CTE récursive infinie
Virgule finale
WITH :