Използвайте 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);
Използвах цитиране на долари за първия параметър, който няма специално значение. Просто е удобно да избягвате единични кавички в низа на заявката, което е често срещан случай:
- Вмъкнете текст с единични кавички в PostgreSQL
Подробно обяснение и инструкции:
- PostgreSQL Crosstab Query
И по-специално за "допълнителни колони":
- Завъртане на множество колони с помощта на Tablefunc
Специалните трудности тук са:
-
Липсата на ключови имена.
--> Заменяме сrow_number()
в подзаявка. -
Различният брой имейли.
--> Ограничаваме до макс. от три във външнияSELECT
и използвайтеcrosstab()
с два параметъра, предоставящ списък с възможни ключове.
Обърнете внимание на NULLS LAST
в ORDER BY
.