質問

バックグラウンド

5300以上の重複行:

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

追加の詳細:

  • PostgreSQL 8.4データベース
  • Linux

問題

一部の値は明らかな複製です(領域が一致し、2つの場所がそのような近接しているために「ABバリック」であるため「アバイ」)、他の値はそれほど明白ではありません(そして実際の複製さえしないかもしれません):

"1919430","27.4263889","57.5725","IR","29","`Abbasabad"
"1919435","36.5641667","61.14","IR","30","`Abbasabad"

目標は、すべての複製を排除することです。

質問

上記のCSVデータなどの値の表が与えられます。

  • 重複をどのように排除しますか?
  • どのジオ中心のPostgreSQL関数を使用しますか?
  • 重複を倒すために他のどの基準を使用しますか?

アップデート

近接しているのと同じ国内の重複した都市名(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

アイデア

2位のアプローチ:

  1. Min(ID)を削除することにより、明らかな複製(同じ国、地域、都市名)を排除します。
  2. 同じ名前と国を持っている互いに近接している人々を排除します。これにより、いくつかの正当な都市が削除される可能性がありますが、結果はほとんどありません。

ありがとうございました!

役に立ちましたか?

解決 2

これにより、同じ国の同じ名前の都市に近接している2番目の都市が削除されます。

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
)

他のヒント

複製を見つけることは簡単です:

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;

これに基づいて複製を削除するコードを追加することは簡単です:

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
)

削除クエリにあることがないことに注意してください。

データがCSVファイルを通じてインポートされ、コード(PHP)を使用してインポートされている場合、PHPコードのパッティング条件でエントリを複製するのを防ぐことができます。挿入した都市がすでに存在している場合は、ループを次のレコードに進み、現在のレコードをスキップします。

この方法に従ってデータベースにデータをインポートする場合は、これを試してください。

ありがとう。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top