Maison >base de données >tutoriel mysql >Pourquoi plusieurs fonctions de retour d'ensemble dans une clause SELECT ne produisent-elles pas toujours une jointure croisée dans PostgreSQL ?

Pourquoi plusieurs fonctions de retour d'ensemble dans une clause SELECT ne produisent-elles pas toujours une jointure croisée dans PostgreSQL ?

Barbara Streisand
Barbara Streisandoriginal
2025-01-17 23:57:09127parcourir

Why Do Multiple Set-Returning Functions in a SELECT Clause Not Always Produce a Cross Join in PostgreSQL?

Comportement inattendu de PostgreSQL avec plusieurs fonctions de retour d'ensemble dans les SELECT instructions

Le problème :

L'utilisation de plusieurs fonctions renvoyant un ensemble dans la clause d'une instruction SELECT peut donner des résultats inattendus, en particulier lorsque les ensembles ont des longueurs inégales. Alors que generate_series(1, 3) et generate_series(5, 7) produisent une jointure croisée, generate_series(1, 2) et generate_series(1, 4) ne le font pas. Cette incohérence est déroutante.

L'explication :

La clé réside dans les différences de version de PostgreSQL. PostgreSQL 10 et les versions ultérieures gèrent cela différemment des versions antérieures (9.6 et antérieures).

PostgreSQL 10 et versions ultérieures :

PostgreSQL 10 et les versions ultérieures traitent plusieurs fonctions renvoyant un ensemble dans la liste SELECT de la même manière qu'une clause LATERAL ROWS FROM(...). Les fonctions s'exécutent de manière synchrone et les ensembles les plus courts sont complétés par des valeurs NULL pour correspondre à la longueur de l'ensemble le plus long. Cela garantit une jointure croisée complète. Par exemple :

<code>row2 | row3 | row4
-----+------+-----
1 | 11 | 21
2 | 12 | 22
NULL | 13 | 23
NULL | NULL | 24</code>

PostgreSQL 9.6 et versions antérieures :

Dans les anciennes versions (9.6 et antérieures), le nombre de lignes de l'ensemble de résultats était égal au plus petit commun multiple (LCM) du nombre de lignes de la fonction individuelle. Une jointure croisée ne se produisait que si les tailles définies ne partageaient aucun diviseur commun. En utilisant le même exemple, le résultat serait :

<code>row2 | row3 | row4
-----+------+-----
1 | 11 | 21
2 | 12 | 22
1 | 13 | 23
2 | 11 | 24
1 | 12 | 21
2 | 13 | 22
1 | 11 | 23
2 | 12 | 24
1 | 13 | 21
2 | 11 | 22
1 | 12 | 23
2 | 13 | 24</code>

Bonnes pratiques :

Pour éviter des résultats inattendus, il est préférable d'utiliser des jointures ou des sous-requêtes LATERAL au lieu de placer directement plusieurs fonctions renvoyant un ensemble dans la liste SELECT. Cela offre un contrôle plus clair et un comportement prévisible.

Pour plus de détails et informations associées, consultez la documentation officielle de PostgreSQL :

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn