Eliminare città duplicati dal database
-
26-10-2019 - |
Domanda
Sfondo
Oltre 5300 righe duplicate:
"id","latitude","longitude","country","region","city"
"2143220","41.3513889","68.9444444","KZ","10","Abay"
"2143218","40.8991667","68.5433333","KZ","10","Abay"
"1919381","33.8166667","49.6333333","IR","34","Ab Barik"
"1919377","35.6833333","50.1833333","IR","19","Ab Barik"
"1919432","29.55","55.5122222","IR","29","`Abbasabad"
"1919430","27.4263889","57.5725","IR","29","`Abbasabad"
"1919413","28.0011111","58.9005556","IR","12","`Abbasabad"
"1919435","36.5641667","61.14","IR","30","`Abbasabad"
"1919433","31.8988889","58.9211111","IR","30","`Abbasabad"
"1919422","33.8666667","48.3","IR","23","`Abbasabad"
"1919420","33.4658333","49.6219444","IR","23","`Abbasabad"
"1919438","33.5333333","49.9833333","IR","34","`Abbasabad"
"1919423","33.7619444","49.0747222","IR","24","`Abbasabad"
"1919419","34.2833333","49.2333333","IR","19","`Abbasabad"
"1919439","35.8833333","52.15","IR","35","`Abbasabad"
"1919417","35.9333333","52.95","IR","17","`Abbasabad"
"1919427","35.7341667","51.4377778","IR","26","`Abbasabad"
"1919425","35.1386111","51.6283333","IR","26","`Abbasabad"
"1919713","30.3705556","56.07","IR","29","`Abdolabad"
"1919711","27.9833333","57.7244444","IR","29","`Abdolabad"
"1919716","35.6025","59.2322222","IR","30","`Abdolabad"
"1919714","34.2197222","56.5447222","IR","30","`Abdolabad"
Ulteriori dettagli:
- PostgreSQL 8.4 database
- Linux
Problema
Alcuni valori sono evidenti duplicati ( "Abay" perché le regioni corrispondono e "Ab Barik" perché le due posizioni sono in tale vicinanza), altri non sono così evidenti (e potrebbero anche non essere duplicati reali):
"1919430","27.4263889","57.5725","IR","29","`Abbasabad"
"1919435","36.5641667","61.14","IR","30","`Abbasabad"
L'obiettivo è quello di eliminare tutti i duplicati.
Domande
Data una tabella di valori quali i dati sopra CSV:
- Come vi eliminare i duplicati?
- Che geo-centric funzioni PostgreSQL useresti?
- Quali altri criteri usereste per carpire le duplicati?
Aggiorna
semi-funzionante esempio di codice per selezionare i nomi delle città duplicati all'interno dello stesso paese che si trovano nelle immediate vicinanze (a 10 km):
select
c1.country, c1.name, c1.region_id, c2.region_id, c1.latitude_decimal, c1.longitude_decimal, c2.latitude_decimal, c2.longitude_decimal
from
climate.maxmind_city c1,
climate.maxmind_city c2
where
c1.country = 'BE' and
c1.id <> c2.id and
c1.country = c2.country and
c1.name = c2.name and
(c1.latitude_decimal <> c2.latitude_decimal or c1.longitude_decimal <> c2.longitude_decimal) and
earth_distance(
ll_to_earth( c1.latitude_decimal, c1.longitude_decimal ),
ll_to_earth( c2.latitude_decimal, c2.longitude_decimal ) ) <= 10
order by
country, name
Idee
approccio fase due:
- Eliminare i duplicati evidenti (stesso paese, regione e città) rimuovendo il min (id).
- eliminare quelle nelle immediate vicinanze l'uno dall'altro, che ha lo stesso nome e il paese. Questo potrebbe rimuovere alcune città legittimi, ma quasi nessuno di conseguenza.
Grazie!
Soluzione 2
Questo elimina la seconda città nelle immediate vicinanze di una città con lo stesso nome nello stesso paese:
delete from climate.maxmind_city mc where id in (
select
max(c1.id)
from
climate.maxmind_city c1,
climate.maxmind_city c2
where
c1.id <> c2.id and
c1.country = c2.country and
c1.name = c2.name and
earth_distance(
ll_to_earth( c1.latitude_decimal, c1.longitude_decimal ),
ll_to_earth( c2.latitude_decimal, c2.longitude_decimal ) ) <= 35
group by
c1.country, c1.name
order by
c1.country, c1.name
)
Altri suggerimenti
la ricerca di duplicati è semplice:
select
max(id) as this_should_stay,
latitude,
longitude,
country,
region,
city
FROM
your_table
group by
latitude,
longitude,
country,
region,
city
having count(*) > 1;
L'aggiunta di codice per i duplicati rimuovere sulla base di questo è semplice:
delete from your_table where id not in (
select
max(id) as this_should_stay
FROM
your_table
group by
latitude,
longitude,
country,
region,
city
)
nota la mancanza di avere nella query di eliminazione.
Se i dati sono stati importati attraverso file CSV e con il codice (PHP) allora si può impedire l'ingresso duplicati con la condizione messa in codice PHP. se la città è stato inserito è già presente poi fare loop di continuare a record successivo e saltare record corrente.
provare questo se siete seguire questo modo di importare i dati nel database ..
Grazie.