2017-02-02 2 views
0

私はPostgreSQLに2つのテーブルを持っています。寄付のあるテーブルと機能を備えたテーブル。私は各機能にdonation_idを割り当てたいが、いくつかのdonation_idは、寄付テーブルの量に基づく機能を持つテーブルの複数のレコードに割り当てる必要があります。PostgreSQL、あるテーブルの複数のレコードを別のテーブルの単一のレコードに割り当てる

たとえば、10人を寄付した場合、2人ごとに1つのdonation_id = 5 donot_idを持つフィーチャーテーブルのレコードにそのフィーチャーを割り当てる必要があります。

フィーチャーが既に存在し、すべてが一意の値を持っているため、私は更新ステートメントを探しています。どの機能がどの寄付に割り当てられるかは重要ではなく、量だけが重要です。

寄付:

donation_id | ammount 
===================== 
001   | 10 
002   | 4 

特長:

feature_id | donation_id | owned 
================================= 
001   | 000   | false 
002   | 000   | false 
003   | 000   | false 
004   | 000   | false 
005   | 000   | false 
006   | 000   | false 
007   | 000   | false 
008   | 000   | false 

出力:

feature_id | donation_id | owned 
================================= 
001   | 001   | true 
002   | 001   | true 
003   | 001   | true 
004   | 001   | true 
005   | 001   | true 
006   | 002   | true 
007   | 002   | true 
008   | 000   | false 
+2

**ご質問ください**あなたの質問といくつかのサンプルデータとそのデータに基づいて予想される出力を追加します。 [**フォーマットされたテキスト**](http://stackoverflow.com/help/formatting)、[スクリーンショットなし](http://meta.stackoverflow.com/questions/285551/why-may-i-not 285557#285557) –

+0

寄付が2の倍数でない場合はどうなりますか?寄付を受け取るための十分な機能がない場合はどうなりますか? –

+0

寄付金が2の倍数でない場合は、それを丸める必要があります。十分な機能があります。 – Titsjmen

答えて

0

あなたが遊んで、Common Table Expression(または2つの一時テーブル、またはいくつかのサブクエリと冗長性)を使用することができますいくつかのトリックで:

  1. CROSS JOIN(デカルト製品)は、generate_seriesを使用して繰り返し行を取得できます。 [それらを区別できるようにrow_number()カラムを追加します]
  2. feature_idを、そして式を使用してLIMITを行数で指定することができます。ここでも、row_number()列を追加して区別することができます。だから、

、次のコードは、トリックん:

  • 私はfeature_idがあると仮定してきた:あなたはRexTester


    NOTESでそれを

    -- Get a (virtual) table with "donation_id" repeated as many times 
    -- as (amount/2). Trick: use a CROSS JOIN with generate_series 
    WITH new_features AS 
    (
        SELECT 
         donation_id, row_number() over() AS rn 
        FROM 
         donations 
         CROSS JOIN generate_series(1, amount/2) AS g(i) 
    ), 
    -- Right now we know how many rows we want to UPDATE. 
    -- The next SELECT chooses them. Trick: computed LIMIT 
    to_update AS 
    (
        SELECT 
         feature_id, row_number() over() AS rn 
        FROM 
         features 
        WHERE 
         NOT owned 
        ORDER BY 
         feature_id -- This is arbitrary, it could even not be sorted. 
        LIMIT 
         (SELECT count(*) FROM new_features) 
    ) 
    -- ... and finally 
    UPDATE 
        features 
    SET 
        donation_id = new_features.donation_id, owned = true 
    FROM 
        to_update 
        JOIN new_features USING(rn) 
    WHERE 
        features.feature_id = to_update.feature_id 
    RETURNING 
        features.feature_id, features.donation_id, features.owned ; 
    

    を確認することができます主キー(または代替キー:一意かつnullではない)。これが真実でない場合は、適切なPKが必要です。

  • owned列を使用する代わりに、NULLnot ownedを意味するときに、donation_idを持つことができます。それは更新する必要のない列を節約します。
関連する問題