Utilisez crosstab()
depuis le module 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);
J'ai utilisé des citations en dollars pour le premier paramètre, qui n'a pas de signification particulière. Il est simplement pratique d'échapper les guillemets simples dans la chaîne de requête, ce qui est un cas courant :
- Insérer du texte avec des guillemets simples dans PostgreSQL
Explication détaillée et instructions :
- Requête croisée PostgreSQL
Et en particulier, pour les "colonnes supplémentaires":
- Pivoter sur plusieurs colonnes à l'aide de Tablefunc
Les difficultés particulières voici :
-
Le manque de noms de clés.
--> Nous remplaçons parrow_number()
dans une sous-requête. -
Le nombre variable d'e-mails.
--> Nous limitons à un max. de trois dans leSELECT
externe
et utilisezcrosstab()
avec deux paramètres, fournissant une liste de clés possibles.
Faites attention à NULLS LAST
dans le ORDER BY
.