1

6,500 万行と 140 列をわずかに超えるテーブルがあります。データは複数のソースから取得され、少なくとも毎月送信されます。

このデータから特定のフィールドを一意に取得する簡単な方法を探しています。つまり、すべての情報を処理して、どの請求書がどの識別番号で送信され、誰から送信されたかをリンクしたいと考えています。問題は、6,500 万件を超えるレコードを反復処理したくないということです。個別の値を取得できれば、たとえば 6,500 万件ではなく、500 万件のレコードを処理するだけで済みます。データの説明については以下を参照し、サンプルについてはSQL Fiddleを参照してください。

invoice_numberクライアントがリンク先をpassport_number_1, national_identity_number_1 and driving_license_1毎月送信するとしたら、これが表示される行は 1 つだけ必要です。つまり、4 つのフィールドは一意である必要があります

上記を 30 か月間送信すると、31 か月目にinvoice_numberリンク先が送信されます。フィールドが新しいため、行全体が一意であるためpassport_number_1, national_identity_number_2 and driving_license_1、この行も選択したいと思います。national_identity

  • linked toつまり、それらは同じ行に表示されます
  • すべてのフィールドで、ある時点で Null が発生する可能性があります。
  • 「ピボット/複合」列は、invoice_number と submit_by です。それらのいずれかが存在しない場合は、その行を削除します
  • また、上記のデータに database_id を含める必要があります。つまり、postgresql データベースによって自動生成される primary_id
  • 返す必要のない唯一のフィールドはother_column andyet_another_columnです。テーブルには 140 列あるので必要ないことに注意してください
  • 結果を使用して、この一意のレコードを保持する新しいテーブルを作成します

シナリオを再現する試みについては、このSQL フィドルを参照してください。

そのフィドルから、次のような結果が期待されます。

  • 行 1、2、および行 11: まったく同じであるため、1 つだけを保持する必要があります。できれば最小の行id
  • 行 4 と行 9: まったく同じなので、そのうちの 1 つが削除されます。
  • 行 5、7、および 8: invoice_numberまたはが欠落しているため、削除されsubmitted_byます。
  • 結果は行 (1、2、または 11)、3、(4、または 9)、6、および 10 になります。
4

2 に答える 2

2

4 つの異なるフィールドを持つグループから 1 つの代表的な行 (追加のフィールドを含む) を取得するには:

SELECT 
distinct on (
  invoice_number
  , passport_number
  , national_id_number
  , driving_license_number
)
  * -- specify the columns you want here
FROM my_table
where invoice_number is not null
and submitted_by is not null
;

順序を指定しない限り、どの行が正確に返されるかは予測できないことに注意してください ( のドキュメントdistinct) 。

編集:

id最後に追加するだけでこの結果をorder by id順序付けすることはできませんが、CTE を使用して eiter で実行できます

with distinct_rows as (
    SELECT 
    distinct on (
      invoice_number
      , passport_number
      , national_id_number
      , driving_license_number
      -- ...
    )
      * -- specify the columns you want here
    FROM my_table
    where invoice_number is not null
    and submitted_by is not null
)
select *
from distinct_rows
order by id;

または元のクエリをサブクエリにする

select *
from (
    SELECT 
    distinct on (
      invoice_number
      , passport_number
      , national_id_number
      , driving_license_number
      -- ...
    )
      * -- specify the columns you want here
    FROM my_table
    where invoice_number is not null
    and submitted_by is not null
) t
order by id;
于 2016-07-16T16:32:11.930 に答える
0

このデータから特定のフィールドを一意である場合にのみ取得する簡単な方法

私はそうは思わない。一意ではないテーブルから 個別の行セットを選択したいということだと思います。

あなたの説明からわかる限り、あなたは単に

SELECT distinct invoice_number, passport_number, 
                driving_license_number, national_id_number
FROM my_table
where invoice_number is not null
and submitted_by is not null;

SQLFiddle の例では、5 行が生成されます。

于 2016-07-16T20:44:33.550 に答える