2017-02-05 1 views
-1

Si vous avez une requête qui utilise une sous-requête. Fondamentalement, il est comme ceci:Est-il possible de créer une vue pour une sous-requête renvoyant la requête principale?

SELECT A.name, A.pk 
     array_to_string(array(SELECT B.name FROM b WHERE B.relA = A.pk),', ')  
FROM A; 

Fondamentalement, il fait une colonne dans A d'un à-plusieurs à B. (Dans mon cas A est une liste d'éléments et B contient des balises liées à ce articles. La requête fait une colonne avec une liste de balises pour chaque ligne A.)

Depuis la requête du monde réel est plus complexe et je besoin de la sous-requête plus d'une fois, je veux faire une vue de la sous-requête (DRY). Ce n'est pas possible, car A.pk est seulement connu, si la sous-requête est une sous-requête dans une requête principale qui va de A. On ne sait pas si la sous-requête est autonome. Je ne peux pas créer une vue à partir de la version autonome:

CREATE VIEW bview AS SELECT B.b FROM B WHERE B.relA=A.pk; 

me donne l'attend:

ERROR: missing FROM-clause entry for table "A" 

Est-il possible de définir apparente de « vision incomplète », ce n'est pas exécuté lui-même , mais dans une requête principale complétant la sous-requête sans utiliser de fonctions?

Modifier: La clause WHERE à l'intérieur de la sous-requête ne peut pas être remplacée par une clause JOIN, car elle prend la A.pk de la requête externe.

+0

Ou vous pouvez utiliser CREATE BView VIEW AS SELECT A.pk, B.b DE B JOIN A ON B.relA = A.pk; Et cela: 'SELECT * FROM bview WHERE ' –

+0

@RomanTkachuk Ce n'est pas la même chose car cela crée une nouvelle relation dans la sous-requête. Mais cela devrait prendre le 'A.pk' de la requête principale. J'ai ajouté n explication à la Q. –

Répondre

1

Vous pouvez créer une vue simple, sans se référer à la table A et l'utiliser ensuite comme source de ligne dans différentes parties de votre requête complexe:

CREATE VIEW bview AS 
    SELECT relA, string_agg(name, ', ') AS tags 
    FROM b 
    GROUP BY relA; 

Cela peut sembler inefficace parce que si vous exécutez la vue comme celui-ci sans qualification, toutes les étiquettes pour tous relA sont concaténées. Toutefois, lorsque vous utilisez la vue dans une requête plus importante avec des qualifications, la vue n'est évaluée que pour les valeurs relA demandées dans la requête externe. C'est parce que the view is "merged" with the outer query by the planner.

Alors vous vous retrouvez avec:

SELECT name, pk, tags 
FROM A 
JOIN bview ON relA = pk; 
+0

Ceci est une approche intéressante. Je vais essayer et rapporter le résultat. –

+0

Merci, cela fonctionne. –