Postgres-транспонировать строки в Столбцы
У меня есть следующая таблица, которая дает несколько адресов электронной почты для каждого пользователя.
Мне нужно сгладить это до Столбцов в пользовательском запросе. Чтобы дать мне "новейшие" 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