Use
crosstab()
do módulo 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);
Usei cotações de dólares para o primeiro parâmetro, que não tem nenhum significado especial. É apenas conveniente escapar aspas simples na string de consulta, que é um caso comum:
- Inserir texto com aspas simples no PostgreSQL
Explicação detalhada e instruções:
- Consulta de tabela cruzada PostgreSQL
E, em particular, para "colunas extras":
- Pivotar em várias colunas usando Tablefunc
As dificuldades especiais aqui estão:
-
A falta de nomes de chaves.
--> Substituímos porrow_number()
em uma subconsulta.
-
O número variável de e-mails.
--> Limitamos a um máximo. de três noSELECT
externo
e usecrosstab()
com dois parâmetros, fornecendo uma lista de chaves possíveis.
Preste atenção em
NULLS LAST
no ORDER BY
.