【问题标题】:Delete duplicates based on string length criteria根据字符串长度标准删除重复项
【发布时间】:2011-04-30 04:09:59
【问题描述】:

背景

根据名称的长度从临时表中删除重复的城市名称。

问题

以下查询返回 350,000 行:

select
  tc.id,
  tc.name_lowercase,
  tc.population,
  tc.latitude_decimal,
  tc.longitude_decimal
from
  climate.temp_city tc
inner join (
  select
    tc2.latitude_decimal,
    tc2.longitude_decimal
  from
    climate.temp_city tc2
  group by
    tc2.latitude_decimal,
    tc2.longitude_decimal
  having
    count(*) > 3
) s on 
  tc.latitude_decimal = s.latitude_decimal and
  tc.longitude_decimal = s.longitude_decimal

样本数据:

940308;"sara"            ;;-53.4333333;-68.1833333
935665;"estancia la sara";;-53.4333333;-68.1833333
935697;"estancia sara"   ;;-53.4333333;-68.1833333
937204;"la sara"         ;;-53.4333333;-68.1833333
940350;"seccion gap"     ;;-52.1666667;-68.5666667
941448;"zanja pique"     ;;-52.1666667;-68.5666667
935941;"gap"             ;;-52.1666667;-68.5666667
935648;"estancia gap"    ;;-52.1666667;-68.5666667
939635;"ritchie"         ;;-51.9833333;-70.4
934948;"d.e. ritchie"    ;;-51.9833333;-70.4
934992;"diego richtie"   ;;-51.9833333;-70.4
934993;"diego ritchie"   ;;-51.9833333;-70.4
934990;"diego e. ritchie";;-51.9833333;-70.4

我想删除所有重复项,保留以下行:

  • 人口不为空;和
  • 名称是重复项中最长的(max(tc.name_lowercase));和
  • 如果这两个条件都不满足,请保留max(tc.id)

从给定的数据集中,剩余的行将是:

935665;"estancia la sara";;-53.4333333;-68.1833333
935648;"estancia gap"    ;;-52.1666667;-68.5666667
934990;"diego e. ritchie";;-51.9833333;-70.4

问题

如何只选择具有重复经纬度值且符合问题标准的行?

谢谢!

【问题讨论】:

    标签: sql postgresql duplicate-removal


    【解决方案1】:

    我认为您正在寻找这样的东西:

    SELECT t.id, t.name_lowercase, t.latitude_decimal, t.longitude_decimal
    FROM (SELECT MAX(LENGTH(name_lowercase)) AS len, latitude_decimal, longitude_decimal FROM temp_city GROUP BY latitude_decimal, lng) AS max_length,
         temp_city t
    WHERE max_length.latitude_decimal  = t.latitude_decimal
      AND max_length.longitude_decimal = t.longitude_decimal
      AND max_length.len = LENGTH(t.name_lowercase);
    

    temp_city 是包含您的样本结果的表格。

    如果您的temp_city 也包含此行,则上述内容会遇到问题:

    1 | xxxancia la sara | -53.4333333 | -68.1833333
    

    您没有提供从name 具有最大长度的行中选择哪一行的方法,因此这两个都将被返回:

          1 | xxxancia la sara | -53.4333333 | -68.1833333
     935665 | estancia la sara | -53.4333333 | -68.1833333
    

    更新:如果max(tc.id) 是修剪上述重复项的额外标准,那么您可以在上面再包裹一层:

    SELECT t.id, t.name_lowercase, t.latitude_decimal, t.longitude_decimal
    FROM  
      (
        SELECT MAX(t.id) AS id
        FROM
          (
            SELECT MAX(LENGTH(name_lowercase)) AS len, latitude_decimal, longitude_decimal
            FROM temp_city
            GROUP BY latitude_decimal, longitude_decimal
          ) AS max_length,
          temp_city t
        WHERE max_length.latitude_decimal  = t.latitude_decimal
          AND max_length.longitude_decimal = t.longitude_decimal
          AND max_length.len               = LENGTH(t.name_lowercase)
        GROUP BY t.latitude_decimal, t.longitude_decimal, LENGTH(t.name_lowercase)
      ) AS tt, 
      temp_city t
    WHERE t.id = tt.id
    

    【讨论】:

    • 谢谢。 max(tc.id) 是打破平局的标准。
    • @Dave:我添加了一个更新,应该处理那个决胜局。这个查询变得相当可怕,尽管没有向任何孩子或容易受到惊吓的成年人展示。
    • 谢谢;重复的坐标已被根除。
    猜你喜欢
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 2021-05-01
    • 2011-02-25
    • 2021-07-04
    • 1970-01-01
    相关资源
    最近更新 更多