这是我的数据:
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。我想要的是,对于我找到的每个副本以及表格视图中的每一列,如果该单元格中存在数据,那么,如果存在,则尝试将其转储到该人的最旧记录,如果有数据,什么都不做。
我不知道自己是否清楚自己。
这样做的最佳方法是什么?我应该编写一个存储过程,还是可以通过一个聪明的查询来完成我还没想到呢?
答案 0 :(得分:2)
您可以像这样创建自定义聚合:
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
。
P.S。聚合函数来自Custom aggregate function
答案 1 :(得分: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
;
尝试使用针对Igor自定义聚合的真实数据测试此方法,以了解哪种方法表现更好。