web-dev-qa-db-ja.com

Postgres-行を列に転置

次の表は、ユーザーごとに複数の電子メールアドレスを示しています。

enter image description here

これをユーザークエリの列にフラット化する必要があります。作成日に基づいて「最新」の3つのメールアドレスを教えてください。

user.name | user.id | email1          | email2           | email3**

Mary      | 123     | [email protected]  | [email protected] | [email protected]

Joe       | 345     | [email protected]   | [NULL]           | [NULL]
33
dacology

tablefunc モジュールのcrosstab()を使用します。

_SELECT * FROM crosstab(
   $$SELECT user_id, user_name, rn, email_address
     FROM  (
        SELECT u.user_id, u.user_name, e.email_address
             , row_number() OVER (PARTITION BY u.user_id
                            ORDER BY e.creation_date DESC NULLS LAST) AS rn
        FROM   usr u
        LEFT   JOIN email_tbl e USING (user_id)
        ) sub
     WHERE  rn < 4
     ORDER  BY user_id
   $$
  , 'VALUES (1),(2),(3)'
   ) AS t (user_id int, user_name text, email1 text, email2 text, email3 text);
_

最初のパラメーターには特別な意味のないドル引用符を使用しました。一般的なケースであるクエリ文字列内の単一引用符をエスケープする必要がある場合に便利です。

詳細な説明と手順はこちら:

特に、「余分な列」の場合:

特別な困難は次のとおりです。

  • キー名の欠如。
    ->サブクエリで row_number() に置き換えます。

  • さまざまな数のメール。
    ->最大値に制限します。外側の3つのSELECT
    そしてcrosstab()を2つのパラメーターとともに使用して、可能なキーのリストを提供します。

_NULLS LAST_の _ORDER BY_に注意してください

44

この質問を見つけて、これに動的な解決策を必要とする誰かが正確に3つではなく未定義の列数を転置する必要がある場合、ここでニースの解決策を見つけることができます: https://github.com/ jumpstarter-io/colpivot

12

上記のコードは本当に助けになりました。今、ピボットテーブルにフィールドを追加しようとしています。

    SELECT * INTO temp_pivot_table FROM crosstab(
    $$SELECT lead_id, magazine_id, days_between_mailers, rn
    FROM  (
    SELECT u.lead_id, u.magazine_id, u.days_between_mailers
         , row_number() OVER (PARTITION BY u.lead_id
                        ORDER BY u.id ASC NULLS LAST) AS rn
    FROM   temp_mailer_stats u
    ) sub
    WHERE  rn <= 3
    ORDER  BY lead_id
   $$

  , 'VALUES (1),(2),(3),(4),(5),(6)'
  ) AS t (lead_id int, magazine1 text, magazine2 text, magazine3 text, 
   days_between1 integer, days_between2 integer, days_between3 integer);

もちろん、別々のテーブルを作成してからそれらを結合することもできますが、理想的なステップを保存できる場合。

助けてくれてありがとう。

0
ja11946