Nach - ich weiß nicht, was passiert ist - werden alle meine Einträge in meinen PostGIS-Tabellen verdoppelt! Ich habe versucht, sie zu löschen, aber es werden keine / alle Duplikate gelöscht:
DELETE FROM planet_osm_point
WHERE osm_id NOT IN (SELECT min(osm_id)
FROM planet_osm_point
GROUP BY osm_id)
oder dieses:
DELETE FROM planet_osm_point
WHERE osm_id NOT IN (
select max(dup.osm_id)
from planet_osm_point as dup
group by way);
BEARBEITEN:
Ich habe endlich einen einfachen Weg gefunden, der in meinem Fall funktioniert:
DELETE FROM planet_osm_point WHERE ctid NOT IN
(SELECT max(ctid) FROM planet_osm_point GROUP BY osm_id);
auf dieser Seite gefunden: http://technobytz.com/most-useful-postgresql-commands.html
qgis
postgis
osm2pgsql
duplication
KARTE
quelle
quelle
planet_osm_point
Tabellenstruktur angeben? bedeutet Art der Spalten. Sie können einen grundlegenden Python-Code schreiben, um die ausgewählten Spalten zu erfassen, wenn Sie Probleme mit den SQL-Funktionen haben.ctid
Ansatz nicht verstanden. Diese Spalte wurde nach dem Duplizierungsereignis manuell hinzugefügt.Antworten:
Eine Möglichkeit, dies zu tun, besteht darin, eine Fensterfunktion und eine Partition nach Geometrie zu verwenden, sodass jede wiederholte Geometrie eine ID erhält: 1, 2, 3 usw. (oder 1, 2) in Ihrem Fall, und dann wählen Sie einfach aus Tabelle mit der ID = 1, um einen eindeutigen Satz von Werten (Attribute und Geometrie) zurückzugewinnen, z.
Natürlich müssten Sie auch die anderen osm-Spalten in die Auswahl einfügen. Dies dient nur zur Veranschaulichung, entspricht jedoch im Wesentlichen der Gruppierung nach Geometrie und der Auswahl der ersten Instanz jeder einzelnen Spalte. Beachten Sie, dass Sie ST_AsBinary in der Partition By verwenden müssen, da sonst der Vergleich für den Begrenzungsrahmen und nicht für die tatsächliche Geometrie erfolgt.
Da alle anderen Attribute vermutlich für jedes Geometriepaar gleich sind, würden Sie so etwas für alle anderen Felder, einschließlich osm_id, tun und tatsächlich eine neue, eindeutige Tabelle erstellen:
Dies ist möglicherweise schneller als das Löschen aus einer vorhandenen Tabelle, insbesondere wenn viele Indizes vorhanden sind.
BEARBEITEN . Zur besseren Lesbarkeit umgeschrieben, aber dbaston die Ehre überlassen , meine Aufmerksamkeit auf ST_AsBinary (geom) zu lenken
quelle
Partition By
?PARTITION BY
der=
Operator verwendet wird, der die Gleichheit von Begrenzungsrahmen bearbeitet). Ich würde vorschlagen, das oben genanntePARTITION BY ST_AsBinary(geom)
als Korrektur zu ändern .Hier ist eine andere Methode, mit der ich Duplikate aus einem SSURGO-Bodendaten-Download entfernt habe. Die heruntergeladenen Shapefiles hatten keinen eindeutigen Schlüssel, daher wurde beim Importieren in PostGIS eine serielle pk-Spalte generiert. Es gab einige Überlappungen in den Datensätzen, und ich habe versehentlich einige Datensätze mehr als einmal importiert, während ich das Importskript entwickelt habe.
Die Anweisung group by enthält alle Spalten in der Tabelle mit Ausnahme des Primärschlüssels.
Bei jeder Ausführung wird nur ein Satz doppelter Zeilen gelöscht. Wenn eine Zeile also viermal wiederholt wird, müssen Sie diese mindestens dreimal ausführen. Dies ist wahrscheinlich nicht so schnell wie Johns Lösung, funktioniert jedoch innerhalb einer vorhandenen Tabelle. Dies funktioniert auch, wenn Sie nicht für jede eindeutige Geometrie eine eindeutige ID haben (z. B. die osm_id in der ursprünglichen Frage).
Ich benutzte ein Python-Skript, um zu wiederholen, bis Duplikate verschwunden waren, und ließ dann ein volles Vakuum laufen. Ich denke, das Skript und das Vakuum dauerten jeweils etwa 30 Minuten für einige hunderttausend Duplikate von etwa 1,5 Millionen Datensätzen in 6 Tabellen. Viel Gutes für ein Einzelstück. Es ging sehr schnell durch die kleinen Tische.
BEARBEITEN: SQL wurde geändert, um zu vermeiden, dass es basierend auf dem @ dbaston-Vorschlag (siehe unten) mehrmals ausgeführt wird. Ich habe diese Abfragemethode in einer großen Tabelle (~ 1,5 Millionen Datensätze, ~ 25.000 doppelte Punktzeilen) ausprobiert und nach 45 Minuten die Ausführung abgebrochen. Das Ausführen mit dem obigen SQL (unter Verwendung einer kleineren Unterabfrage aus dem HAVING COUNT) reduzierte jeden Lauf auf weniger als 30 Sekunden. Nach dreimaligem Ausführen wurde dies mit allen Duplikaten durchgeführt. Die folgende SQL sollte für kleine Tabellen in Ordnung sein.
quelle
ctid
Spalte verwenden (siehe Dokumente ).primary_key NOT IN (SELECT max(primary_key) ....
Eine allgemeinere Antwort zum einfachen Löschen von Geometrieduplikaten in der PostGIS-Tabelle. Der folgende Befehl löscht alle Features mit doppelter Geometrie in "tabellenname" basierend auf dem Primärschlüssel (Spalte "gid") und der Gleichheit der Geometrie (Spalte "geom"). Beachten Sie, dass wirklich alle Geometrieduplikate gelöscht werden. Sie werden für immer verschwunden sein! Vielleicht zuerst sichern?
quelle