2

これが私のデータです:

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を持つ複数のソースから埋められています。私が欲しいのは、見つけた重複ごと、およびテーブルビューの各列について、そのセルにデータが存在する場合は、存在する場合はその人の最も古いレコードにダンプしてみてください。データがある場合は、何もしない。

自分をはっきりさせたかどうかはわかりません。

これを行うための最良のアプローチは何ですか?ストアドプロシージャを作成する必要がありますか、それともまだ思い付いていない巧妙なクエリで実行できますか?

4

2 に答える 2

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
);

最初のnotnull値を返します。それで:

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、必要なデータを使用してを作成します。

PS集計関数は、カスタム集計関数からのものです

于 2012-11-28T21:21:51.783 に答える
2

これは、結合関数とウィンドウ関数を使用したクエリで解決できます。

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のカスタム集計に対して実際のデータでこのアプローチをテストして、どちらが優れているかを確認してください。

于 2012-11-29T01:36:54.567 に答える