Después, no sé qué pasó, ¡todas mis entradas en mis tablas de PostGIS se duplican! Intenté esto para eliminarlos, pero no elimina ninguno / todos los duplicados:
DELETE FROM planet_osm_point
WHERE osm_id NOT IN (SELECT min(osm_id)
FROM planet_osm_point
GROUP BY osm_id)
o esto:
DELETE FROM planet_osm_point
WHERE osm_id NOT IN (
select max(dup.osm_id)
from planet_osm_point as dup
group by way);
EDITAR:
Finalmente encontré una manera fácil, que está funcionando en mi caso:
DELETE FROM planet_osm_point WHERE ctid NOT IN
(SELECT max(ctid) FROM planet_osm_point GROUP BY osm_id);
encontrado en esta página: http://technobytz.com/most-useful-postgresql-commands.html
planet_osm_point
estructura de la tabla actual ? significa tipo de columnas. Puede escribir un código básico de Python para recopilar las columnas seleccionadas, si tiene dificultades con las funciones de SQL.ctid
enfoque. ¿Esta columna se ha agregado manualmente después del evento de duplicación?Respuestas:
Una forma de hacerlo es utilizar una función de ventana y una partición por geometría, de modo que cada geometría repetida obtenga una identificación: 1, 2, 3, etc. (o 1, 2) en su caso, y luego simplemente seleccione de tabla donde id = 1, para recuperar un conjunto único de valores (atributos y geometría), por ejemplo,
Obviamente, también necesitaría agregar las otras columnas de osm en la selección, esto es solo para ilustración, pero esto es básicamente como agrupar por geometría y simplemente seleccionar la primera instancia de cada una. Tenga en cuenta que debe usar ST_AsBinary en Partition By ya que, de lo contrario, la comparación se realiza en el cuadro delimitador, no en la geometría real.
Como todos los demás atributos son presumiblemente los mismos para cada par de geometría, sería algo así para todos los demás campos, incluido osm_id, y para crear una tabla nueva y única:
Esto podría ser más rápido que eliminar de una tabla existente, especialmente si hay muchos índices en su lugar.
EDITAR . Reescrito para facilitar la lectura, pero dejando el crédito a dbaston por llamar mi atención sobre ST_AsBinary (geom)
fuente
Partition By
?PARTITION BY
utiliza el=
operador, que funciona en la igualdad del cuadro delimitador). Sugeriría cambiar lo anteriorPARTITION BY ST_AsBinary(geom)
como una solución.Aquí hay otro método que usé para eliminar duplicados de una descarga de datos de suelo SSURGO. Los archivos de forma descargados no tenían una clave única, por lo que se generó una columna pk en serie cuando importé a PostGIS. Hubo algunas superposiciones en los conjuntos de datos, y sin querer importé algunos registros más de una vez mientras desarrollaba el script de importación.
El grupo por declaración incluye todas las columnas de la tabla, excluyendo la clave primaria.
Solo eliminará un conjunto de filas duplicadas cada vez que se ejecute, por lo que si una fila se repite 4 veces, deberá ejecutar esto un mínimo de 3 veces. Es probable que esto no sea tan rápido como la solución de John, pero funciona dentro de una tabla existente. También funciona cuando no tiene una identificación única para cada geometría única (como el osm_id en la pregunta original).
Usé un script de Python para repetir hasta que desaparecieron los duplicados, y luego ejecuté un vacío completo. Creo que el guión y el vacío tomaron aproximadamente 30 minutos para unos cientos de miles de duplicados de alrededor de 1.5 millones de registros en 6 tablas. Mucho bueno para una sola vez. Atravesó las mesas pequeñas muy rápidamente.
EDITAR: SQL modificado para evitar ejecutar varias veces según la sugerencia de @dbaston (a continuación). Probé este método de consulta en una tabla grande (~ 1.5 millones de registros, ~ 25,000 filas de puntos duplicados), y después de que se ejecutó durante 45 minutos, cancelé su ejecución. Ejecutar con el SQL anterior (usando una subconsulta más pequeña de HAVING COUNT) redujo cada ejecución a menos de 30 segundos. Después de correr 3 veces, se hizo con todos los duplicados. El SQL a continuación debería estar bien para tablas pequeñas.
fuente
ctid
columna siempre disponible (ver documentos ).primary_key NOT IN (SELECT max(primary_key) ....
Una respuesta más general para eliminar fácilmente los duplicados de geometría en la tabla PostGIS. El siguiente comando elimina todas las características con geometría duplicada en "nombre_tabla" en función de la clave primaria (columna "gid") y la igualdad de geometría (columna "geom"). Tenga en cuenta que realmente elimina todos los duplicados de geometría, ¡se habrán ido para siempre! Tal vez una copia de seguridad primero?
fuente