Solución:
Usar crosstab()
desde el 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);
Usé cotizaciones en dólares para el primer parámetro, que no tiene un significado especial. Es conveniente si tiene que escapar de las comillas simples en la cadena de consulta, que es un caso común:
- Insertar texto con comillas simples en PostgreSQL
Explicación e instrucciones detalladas aquí:
- Consulta de tabla cruzada de PostgreSQL
Y en particular, para “columnas adicionales”:
- Girar en varias columnas usando Tablefunc
los dificultades especiales aquí están:
-
La falta de nombres clave.
-> Sustituimos conrow_number()
en una subconsulta. -
El número variable de correos electrónicos.
-> Limitamos a un máximo. de tres en el exteriorSELECT
y use
crosstab()
con dos parámetros, proporcionando una lista de posibles claves.
Presta atencion a NULLS LAST
en el ORDER BY
.
Si alguien más encuentra esta pregunta y necesita una solución dinámica para esto donde tiene un número indefinido de columnas para transponer y no exactamente 3, puede encontrar una buena solución aquí: https://github.com/jumpstarter-io/ colpivot