2016-02-18 2 views
1

Nous utilisons une connexion Postgres/PostGis pour obtenir des données qui sont publiées via un geoserver.Requête UNION ALL dynamique dans Postgres

La requête ressemble à ceci au moment:

SELECT 
    row_number() over (ORDER BY a.ogc_fid) AS qid, a.wkb_geometry AS geometry 
FROM 
(
    SELECT * FROM test 
    UNION ALL 
    SELECT * FROM test1 
    UNION ALL 
    SELECT * FROM test2 
)a 

Dans notre db seulement shapefiles valides seront importées chacun dans une seule table il serait logique de faire l'UNION ALL partie dynamique (boucle sur chaque table et faites la déclaration UNION ALL). Existe-t-il un moyen de le faire de manière standard à Postgres ou dois-je écrire une fonction et à quoi ressemblerait la syntaxe? Je suis assez nouveau à SQL.

Les fichiers de formes ont une structure de données différente et seules la colonne ogc_fid et la colonne wkb_geometry sont toujours disponibles et nous souhaitons regrouper toutes les tables de la base de données.

+0

Je ne sais pas vraiment ce que cette chose est shapefile, mais pourquoi ne pas importer juste tout en une seule table? Une autre option serait d'utiliser l'héritage de table –

+0

Votre question n'est pas vraiment claire. Donc la réponse dépend de ce que vous voulez faire. Mais la solution facile est de créer un [** DYNAMIC QUERY **] (http://www.postgresql.org/docs/9.4/static/ecpg-dynamic.html) mais vous avez besoin d'un moyen de savoir quelles sont les tables que vous voulez rejoindre –

+0

dans les fichiers de formes, vous pouvez stocker des données géographiques. Nous voudrions éviter de tout stocker dans une seule table car la structure de données des géodonnées peut être différente et nous aimerions garder toutes les colonnes de chaque fichier pour d'autres requêtes –

Répondre

1

Ceci est juste des directives générales dont vous avez besoin de travailler dans les détails spécialement syntaxe.

Vous devez créer une procédure de magasin

Créer une boucle de vérification information_schema.tables filtre pour les noms de tables que vous voulez

DECLARE  
    rec record; 
    strSQL text; 
BEGIN 

Ensuite, créez un strSQL avec chaque table

FOR rec IN SELECT table_schema, table_name 
      FROM information_schema.tables     
LOOP 
    strSQL := strSQL || 'SELECT ogc_fid, wkb_geometry FROM ' || 
       rec.table_schema || '.' || rec.table_name || ' UNION '; 
END LOOP; 

-- have to remove the last ' UNION ' from strSQL  

strSQL := 'SELECT row_number() over (ORDER BY a.ogc_fid) AS qid, 
     a.wkb_geometry AS geometry FROM (' || strSQL || ')'; 

EXECUTE strSQL; 
+0

@ClodoaldoNeto Qu'est-ce que vous pensez que c'est SQL Server? –

+0

'@@ FETCH_STATUS' –

+0

Merci. J'ai réparé maintenant :) –

1

Une solution consiste à sérialiser le reste des colonnes à json avec row_to_json(). (disponible depuis PostgreSQL9.2). Pour PG9.1 (et versions antérieures), vous pouvez utiliser hstore, mais notez que toutes les valeurs sont transtypées en texte.

Pourquoi sérialiser? Il n'est pas possible de union lignes où le nombre de colonnes varie, ou les types de données ne correspondent pas entre les requêtes d'union.

J'ai créé un exemple rapide pour illustrer:

--DROP SCHEMA testschema CASCADE; 
CREATE SCHEMA testschema; 

CREATE TABLE testschema.test1 (
    id integer, 
    fid integer, 
    metadata text 
); 

CREATE TABLE testschema.test2 (
    id integer, 
    fid integer, 
    city text, 
    count integer 
); 

CREATE TABLE testschema.test3 (
    id integer, 
    fid integer 
); 


INSERT INTO testschema.test1 VALUES (1, 4450, 'lala'); 
INSERT INTO testschema.test2 VALUES (33, 6682, 'London', 12345); 
INSERT INTO testschema.test3 VALUES (185, 8991); 


SELECT 
    row_number() OVER (ORDER BY a.fid) AS qid, a.* 
FROM 
(
    SELECT id, fid, row_to_json(t.*) AS jsondoc FROM testschema.test1 t 
    UNION ALL 
    SELECT id, fid, row_to_json(t.*) AS jsondoc FROM testschema.test2 t 
    UNION ALL 
    SELECT id, fid, row_to_json(t.*) AS jsondoc FROM testschema.test3 t  
) a 

sortie SELECT:

qid id fid jsondoc 
1; 1; 4450; "{"id":1,"fid":4450,"metadata":"lala"}" 
2; 33; 6682; "{"id":33,"fid":6682,"city":"London","count":12345}" 
3; 185; 8991; "{"id":185,"fid":8991}"