2012-11-28 45 views
2

這裏整合行是我的數據:PostgreSQL中

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。我想要的是,對於我發現的每個副本以及表格視圖中的每個列,如果該單元格中存在數據,那麼如果存在,則嘗試將其轉儲到該人員的最早記錄(如果存在數據)沒做什麼。

我不知道我是否清楚自己。

什麼應該是最好的方法來做到這一點?我應該編寫一個存儲過程,還是可以用一個聰明的查詢完成,我還沒有想出來?

回答

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

嘗試用你的真實數據測試這種方法對伊戈爾的自定義聚合看執行更好。

+0

這種方法就像一個魅力,謝謝你! – BrunoJ

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