Postgres-транспонировать строки в Столбцы

У меня есть следующая таблица, которая дает несколько адресов электронной почты для каждого пользователя.

enter image description here

Мне нужно сгладить это до Столбцов в пользовательском запросе. Чтобы дать мне "новейшие" 3 адреса электронной почты на основе даты создания.

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

Mary      | 123     | mary@gmail.com  | mary@yahoo.co.uk | mary@test.com

Joe       | 345     | joe@gmail.com   | [NULL]           | [NULL]

2 ответов


использовать crosstab() С tablefunc модуль.

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() в подзапросе.

  • различное количество писем.
    - >Мы ограничиваемся максимальным. из трех в внешний SELECT
    и использовать crosstab() с двумя параметрами, предоставляя список возможных ключей.

обратите внимание NULLS LAST на ORDER BY.


Если кто-то еще находит этот вопрос и нуждается в динамическом решении для этого, где у вас есть неопределенное количество столбцов для транспонирования, а не точно 3, Вы можете найти хорошее решение здесь:https://github.com/jumpstarter-io/colpivot