Gebruik crosstab()
uit de tablefun-module.
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);
Ik gebruikte dollar-aanhalingstekens voor de eerste parameter, die geen speciale betekenis heeft. Het is gewoon handig om enkele aanhalingstekens in de queryreeks te laten ontsnappen, wat een veelvoorkomend geval is:
- Tekst invoegen met enkele aanhalingstekens in PostgreSQL
Gedetailleerde uitleg en instructies:
- PostgreSQL-kruistabelquery
En in het bijzonder voor "extra kolommen":
- Op meerdere kolommen draaien met Tablefunc
De speciale moeilijkheden hier zijn:
-
Het ontbreken van sleutelnamen.
--> We vervangen doorrow_number()
in een subquery. -
Het wisselende aantal e-mails.
--> We beperken tot max. van drie in de buitensteSELECT
en gebruikcrosstab()
met twee parameters, die een lijst met mogelijke sleutels bieden.
Let op NULLS LAST
in de ORDER BY
.