One way of doing this, is to use a window function and partition by geometry, so that each repeated geometry gets an id: 1, 2, 3, etc (or 1, 2) in your case, and then you just select from the table where the id = 1
, to get a unique set of values (attributes and geometry) back, e.g.,
WITH unique_geoms (id, geom) AS (
SELECT
row_number() OVER (PARTITION BY ST_AsBinary(geom)) AS id,
geom
FROM some_table
)
SELECT
geom
FROM
unique_geoms
WHERE
id=1;
Obviously, you would need to add the other osm columns in the select too, this is just for illustration, but this is basically like grouping by geometry and just selecting the first instance of each one. Note, you need to use ST_AsBinary()
in the Partition By as otherwise the comparison is done on the bounding box, not the actual geometry.
As all the other attributes are presumably the same for each geometry pair, you would so something like this for all the other fields, including osm_id, and to actually create a new, unique table:
CREATE TABLE osm_unique AS
WITH unique_geoms (id, osm_id, attr1, attr2,... attrn, geom) AS (
SELECT
row_number() OVER (PARTITION BY ST_AsBinary(geom)) AS id,
osm_id, attr1, attr2,... attrn, geom
FROM
osm_planet_point
)
SELECT
osm_id, attr1, attr2,... attrn, geom
FROM
unique_geoms
WHERE
id=1;
This might be quicker than deleting from an existing table, especially if there are lots of indexes in place.
Rewritten for readability, but, leaving the credit to @dbaston for drawing my attention to ST_AsBinary(geom)
.
planet_osm_point
table structure? means type of columns. You can write a basic Python code to collect the selected columns, if having difficulty with the SQL functions.ctid
approach. This column has been added manually after the duplication event?