2016-10-14 1 views
0

En postgreSQL, je crée une table my_table:Comment créer une vue depuis un autre?

DROP SCHEMA IF EXISTS roipoussiere cascade; 
CREATE SCHEMA roipoussiere; 

CREATE TABLE roipoussiere.my_table (
    id SERIAL PRIMARY KEY, 
    x smallint, 
    y smallint); 

INSERT INTO roipoussiere.my_table(x, y) VALUES (42, 42); 
-- [etc.] 

... à partir de laquelle j'ai créé des vues view_a et view_b, qui ont à la fois les mêmes colonnes (mais contenu différent):

DROP VIEW IF EXISTS roipoussiere.view_a CASCADE; 
CREATE VIEW roipoussiere.view_a AS SELECT 
    concat_ws('view_a_', x, '_', y) AS foo, 
    'Hello' AS bar, 
    x, 
    y 
FROM roipoussiere.my_table; 

DROP VIEW IF EXISTS roipoussiere.view_b CASCADE; 
CREATE VIEW roipoussiere.view_b AS SELECT 
    concat_ws('view_b_', x, '_', y) AS foo, 
    'Hello' AS bar, 
    x, 
    y 
FROM roipoussiere.my_table; 

. .. alors j'ai créé la vue my_view, union de view_a et view_b:

DROP VIEW IF EXISTS roipoussiere.my_view CASCADE; 
CREATE VIEW roipoussiere.my_view AS 
    SELECT * FROM roipoussiere.view_a UNION ALL 
    SELECT * FROM roipoussiere.view_b; 

Mais view_a et view_b ont beaucoup de contenu en commun, seulement quelques colonnes sont différentes. Donc, je voudrais éviter la redondance et créer view_a, puis créer view_bdeview_a (sans créer la colonne bar deux fois, ce qui est identique pour toutes les vues).

Note: il est un exemple simplifié, dans la pratique:

  • il y a 4 vues, pas 2; Il existe peu d'autres colonnes comme foo;
  • dizaines d'autres colonnes comme bar (avec des données codées en dur) sur chaque vue.
+0

Êtes-vous à la recherche de 'view view view_b en tant que select ... from view_a'? –

+0

A l'intérieur de '...', dois-je écrire tous les noms de colonnes? – roipoussiere

+0

Si vous ne voulez pas écrire tous les noms de colonne, utilisez 'select *' –

Répondre

1
  1. Vous n'êtes pas « Création d'une colonne » comme ce que vous pensez dans une vue. Une vue ne contient aucune donnée, c'est juste une définition de la manière dont vous "visualisez" les données de la table sous-jacente que la vue référence.
  2. Vous êtes en train de suggérer que vous ALTER la table sous-jacente pour qu'elle corresponde à votre VIEW B, mais si vous faites cela, les résultats de la vue A seront modifiés.
  3. Vous combinez déjà vos vues dans votre UNION. Au lieu de référencer les vues par nom, vous pouvez les référencer directement par le code SQL que vous avez utilisé pour définir la vue. C'est tout pareil.

Ainsi, dans une requête:

Create VIEW roipoussiere.view_c AS 
SELECT 
    concat_ws('view_a_', x, '_', y) AS foo, 
    'Hello' AS bar, 
    x, 
    y 
FROM roipoussiere.my_table 
UNION ALL 
SELECT 
    concat_ws('view_b_', x, '_', y) AS foo, 
    'Hello' AS bar, 
    x, 
    y 
FROM roipoussiere.my_table; 

Chaque fois que vous vous trouvez la création de vues sur le dessus de vues (sur le dessus de vues sur le dessus de vues) vous demander si vous avez vraiment besoin de ces vues sous-jacentes sur les leurs. Exécuterez-vous jamais ViewA par lui-même, ou est-ce juste là pour faciliter l'écriture de View C? Si vous n'en avez pas besoin, ne le faites pas, faites simplement le SELECT dans une sous-requête dans la vue finale. Pour sortir de l'écriture 'Hello' as bar et vos autres champs de type constant encore et encore chacune de vos instructions SELECT qui sont unis ensemble, vous pouvez utiliser un CTE (Common Table Expression) pour le définir une fois dans votre 1 voir et l'utiliser encore et encore.

CREATE VIEW roipoussiere.view_c as 
WITH myCTE AS 
(
    SELECT 

     'Hello' AS bar, 
     'Goodbye' as f1, 
     'Another constant' as f2 
     x, 
     y 
    FROM roipoussiere.my_table 
) 
SELECT 
    concat_ws('view_a_', x, '_', y) AS foo, 
    bar, 
    f1, 
    f2, 
    x, 
    y 
FROM myCTE 
UNION ALL 
SELECT 
    concat_ws('view_b_', x, '_', y) AS foo, 
    bar, 
    f1, 
    f2, 
    x, 
    y 
FROM myCTE 
+0

Donc, '' Hello 'AS barre' est répété, est-il possible de ne pas le répéter? – roipoussiere

+0

L'avez-vous besoin sur cet enregistrement? Avez-vous peur de répéter le code ou de répéter les données? Votre code est dicté par vos besoins. Si vous avez besoin de 'Hello' pour apparaître sur un enregistrement avec ce contenu 'view_b' concaténé, vous devrez l'ajouter comme champ dans votre SELECT. Peut-être partager vos résultats souhaités dans votre question et nous pouvons aider à construire sql pour y parvenir. J'ai toujours le sentiment que vous confondez ce que fait une opinion, mais peut-être que je ne fais que lire votre question de façon incorrecte. – JNevill

+0

J'ai peur de répéter 'Bonjour', parce qu'il y a beaucoup de données comme celle-ci et si quelqu'un veut changer l'un d'entre eux, je veux être sûr que les autres vues auront les mêmes données. – roipoussiere