Uzyskiwanie geometrii z wielu tabel za pomocą PostGIS?

13

Jestem bardzo nowy w PostGIS, PostgreSQL i SQL w ogóle.

Mam 44 tabele w mojej bazie danych PostGIS, a każda z nich reprezentuje inną warstwę danych wektorowych. Każdy został załadowany z osobnego pliku kształtu i każdy ma kolumnę opisującą geometrię tej warstwy, zwanąwkb_geometry

Chcę wybrać konkretny wielokąt na jednej warstwie, a następnie pobrać WSZYSTKĄ geometrię z podzbioru warstw, które zachodzą na obwiednię tego wielokąta. Nie czuję się wybredny, kiedy nadchodzi kolejność, ale byłoby pomocne, gdyby były zorganizowane według tabel, z których pochodziła każda grupa geometrii.

Oto przykład mojej instrukcji SQL:

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
        );

co zwraca błąd:

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

Jak to zrobić?

BenjaminGolder
źródło
1
Przydatny może być nasz SQL Primer. Zaprojektowaliśmy go, aby odpowiadał przede wszystkim na pytania SQL dla początkujących, chociaż obejmuje on również niektóre zaawansowane konstrukcje SQL. postgis.us/chapter_appendix_c Rozdział 1 może być również przydatny, ponieważ jest podkładem przestrzennym PostGIS.
LR1234567,
+1. To są darmowe rozdziały. Kup całą książkę, Benjamin, jest to inwestycja warta. jeśli chcesz dowiedzieć się o PostGIS i wiele więcej.
Nicklas Avén

Odpowiedzi:

8

po pierwsze pojawia się ten komunikat o błędzie, ponieważ nie określiłeś, z której tabeli chcesz wybrać kolumnę geometrii (a ponieważ wszystkie mają taką samą nazwę, postgres się myli). Dlatego pojawia się komunikat o błędzie

odniesienie do kolumny „wkb_geometry” jest niejednoznaczne

Jeśli masz tę samą nazwę kolumny w wielu tabelach, zawsze dodaj nazwę tabeli przed nazwą kolumny: np. table1.wkb_geometry

Twoje zapytanie: jeśli dobrze rozumiem, chcesz znaleźć obiekty na różnych warstwach, które przecinają określony obiekt na jednej określonej warstwie.

Zacznij od patrzenia na dwa tabele na raz, aby było to proste:

Tabela 1 to tabela z określonym obiektem, tabela 2 to tabela z innymi obiektami

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

Teraz, jeśli chcesz dodać dodatkowe obiekty z innych tabel, potrzebujesz UNION ALL, jak już wspomniała Sasa. Nazwy kolumn nie muszą być takie same, ale liczba kolumn i typów danych!

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...

Mogą pojawić się problemy z otwarciem zapytania w przeglądarce, ponieważ nie ma unikalnego identyfikatora. Prostym sposobem rozwiązania tego problemu jest zapisanie wyniku jako tabeli z kolumną id.

baw się dobrze

Tomasz
źródło
6

Nie mam przed sobą klienta SQL, więc może nie być w 100% dokładny, ale będziesz potrzebować czegoś w stylu:

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

i tak dalej. Problem polega na tym, że zapytanie sql nie wie, do której tabeli (table2 / 3/4/5) się odwołujesz, gdy określasz SELECT ST_AsEWKT (wkb_geometry), a zatem niejednoznaczne odniesienie. Możesz również dodać ORDER BY do wyników, jeśli chcesz je zamówić

Sasa Ivetic
źródło