Geometrie aus mehreren Tabellen mit PostGIS erhalten?


13

Ich bin sehr neu in PostGIS, PostgreSQL und SQL im Allgemeinen.

In meiner PostGIS-Datenbank befinden sich 44 Tabellen, von denen jede eine andere Ebene von Vektordaten darstellt. Jedes wurde aus einem separaten Shapefile geladen und verfügt über eine Spalte, die die Geometrie für die genannte Ebene beschreibtwkb_geometry

Ich möchte ein bestimmtes Polygon auf einer Ebene auswählen und dann die gesamte Geometrie aus einer Teilmenge von Ebenen abrufen, die den Begrenzungsrahmen dieses Polygons überlappen. Ich bin nicht wählerisch, was die Reihenfolge angeht, aber es wäre hilfreich, wenn die Tabellen die einzelnen Geometriegruppen enthalten.

Hier ist ein Beispiel meiner SQL-Anweisung:

SELECT
    ST_AsEWKT(wkb_geometry) /* Some of this data has z values, hence the EWKT */
FROM
    table2, table3, table4, table5
WHERE 
    wkb_geometry &&
        (
        SELECT
            wkb_geometry
        FROM
            table1
        WHERE
            ogc_fid = 25
        );

was einen Fehler zurückgibt:

column reference "wkb_geometry" is ambiguous
/* note that every table that I am selecting from has a "wkb_geometry" column */

Was ist der richtige Weg, um dies zu tun?


1
Möglicherweise ist unser SQL Primer hilfreich. Wir haben es entwickelt, um SQL-Anfängerfragen zu beantworten, obwohl es auch einige fortgeschrittene SQL-Konstrukte behandelt. postgis.us/chapter_appendix_c Kapitel 1 kann ebenfalls nützlich sein, da es sich um einen räumlichen PostGIS-Primer handelt.
LR1234567

+1. Das sind die freien Kapitel. Kaufen Sie das ganze Buch, Benjamin, es ist eine Investition wert. wenn Sie mehr über PostGIS und vieles mehr erfahren möchten.
Nicklas Avén

Antworten:


8

Zuallererst erhalten Sie diese Fehlermeldung, weil Sie nicht angegeben haben, aus welcher Tabelle Sie die Geometriespalte auswählen möchten (und da alle denselben Namen haben, wird postgres verwirrt). Deshalb erhalten Sie die Fehlermeldung

Die Spaltenreferenz "wkb_geometry" ist nicht eindeutig

Wenn Sie in mehreren Tabellen denselben Spaltennamen haben, fügen Sie den Tabellennamen immer vor dem Spaltennamen ein: z. table1.wkb_geometry

Zu Ihrer Frage: Wenn ich Sie richtig verstehe, möchten Sie die Objekte in verschiedenen Ebenen finden, die ein bestimmtes Objekt in einer bestimmten Ebene schneiden.

Schauen Sie sich zu Beginn zwei Tische gleichzeitig an, um es einfach zu halten:

Tabelle1 ist die Tabelle mit dem bestimmten Objekt, Tabelle2 die Tabelle mit den anderen Objekten

SELECT
ST_AsEWKT(table2.wkb_geometry)
FROM
table1, table2
WHERE
(table2.wkb_geometry && table1.wkb_geometry)
AND
table1.ogc_fid = 25

Wenn Sie nun zusätzliche Objekte aus anderen Tabellen hinzufügen möchten, benötigen Sie, wie bereits erwähnt, UNION ALL. Spaltennamen müssen nicht identisch sein, aber Anzahl der Spalten und Datentypen!

SELECT
ST_AsEWKT(table2.wkb_geometry)
FROM
table1, table2
WHERE
(table2.wkb_geometry && table1.wkb_geometry)
AND
table1.ogc_fid = 25

UNION ALL

SELECT
ST_AsEWKT(table3.wkb_geometry)
FROM
table1, table3
WHERE
(table3.wkb_geometry && table1.wkb_geometry)
AND
table1.ogc_fid = 25

UNION ALL

etc...

Möglicherweise treten Probleme beim Öffnen der Abfrage in einem Viewer auf, da keine eindeutige ID vorhanden ist. Eine einfache Möglichkeit, dies zu lösen, besteht darin, das Ergebnis als Tabelle mit einer ID-Spalte zu speichern.

habe Spaß


6

Ich habe keinen SQL-Client vor mir, daher ist dieser möglicherweise nicht 100% genau, aber Sie möchten Folgendes:

SELECT ST_AsEWKT(wkb_geometry) FROM table2 WHERE ...
UNION ALL
SELECT ST_AsEWKT(wkb_geometry) FROM table3 WHERE ...

und so weiter. Ihr Problem ist, dass die SQL-Abfrage nicht weiß, auf welche Tabelle (Tabelle2 / 3/4/5) Sie sich beziehen, wenn Sie SELECT ST_AsEWKT (wkb_geometry), also die mehrdeutige Referenz, angeben. Sie können den Ergebnissen auch einen ORDER BY hinzufügen, wenn Sie möchten, dass sie sortiert werden

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.