【问题标题】:Consolidate rows in PostgreSQL在 PostgreSQL 中合并行
【发布时间】:2012-11-16 20:18:08
【问题描述】:

这是我的数据:

ID      FName   LName   data1   data2
1       John    Doe     xxx1    
2       John    Doe     xxx2    yyy2

这是我想要的结果:

ID      FName   LName   data1   data2
1       John    Doe     xxx1    yyy2

简而言之,我有一张桌子,里面有很多人,而且这张桌子是从具有不同数据和 ID 的多个来源填充的。我想要的是,对于我找到的每个重复项以及表格视图中的每一列,如果该单元格中存在数据,那么,如果存在,则尝试将其转储到该人的最旧记录中,如果有数据,什么都不做。

我不知道我是否说清楚了。

最好的方法是什么?我应该编写一个存储过程还是可以通过一个我还没有想出的聪明的查询来完成?

【问题讨论】:

    标签: sql postgresql merge aggregate-functions


    【解决方案1】:

    您可以像这样创建自定义聚合:

    CREATE FUNCTION remember_first(acc text, newval text) RETURNS text AS $$
    BEGIN
        RETURN COALESCE(acc, newval);
    END;
    $$ LANGUAGE plpgsql IMMUTABLE;
    
    CREATE AGGREGATE first(text) (
        sfunc = remember_first,
        stype = text
    );
    

    它将返回第一个不是null 的值。那么:

    SELECT FName, LName, first(data1), first(data2)
    FROM your_table
    GROUP BY FName, LName
    ORDER BY FName, LName, id -- or your ordering columns
    

    获取您需要的数据。最后 - 只需使用此 SELECT 来更新记录。或者只是创建一个带有所需数据的VIEW

    附:聚合函数来自Custom aggregate function

    【讨论】:

      【解决方案2】:

      您可以通过使用连接和window functions 的查询来解决这个问题:

      select nodups.id, nodups.fname, nodups.lname, d1.data1, d2.data2
      from
        (select min(id) as id, fname, lname from sample group by fname, lname) nodups
      left join
        (select fname, lname, min(data1) as data1
         from (select fname, lname
                 , first_value(data1) over (partition by fname, lname order by id) as data1
               from sample where data1 is not null) d1x
         group by fname, lname
        ) d1 using (fname, lname)
      left join
        (select fname, lname, min(data2) as data2
         from (select fname, lname
                 , first_value(data2) over (partition by fname, lname order by id) as data2
               from sample where data2 is not null) d2x
         group by fname, lname
        ) d2 using (fname, lname)
      order by id
      ;
      

      SQLFiddle

      尝试使用您的真实数据对照 Igor 的自定义聚合来测试这种方法,看看哪个效果更好。

      【讨论】:

        猜你喜欢
        • 2015-02-25
        • 1970-01-01
        • 1970-01-01
        • 2012-08-19
        • 2018-02-18
        • 2022-01-26
        • 1970-01-01
        • 2016-06-14
        • 1970-01-01
        相关资源
        最近更新 更多