Brug crosstab()
fra tablefunc-modulet.
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);
Jeg brugte dollar-citering for den første parameter, som ikke har nogen speciel betydning. Det er bare praktisk at undslippe enkelte anførselstegn i forespørgselsstrengen, hvilket er et almindeligt tilfælde:
- Indsæt tekst med enkelte anførselstegn i PostgreSQL
Detaljeret forklaring og instruktioner:
- PostgreSQL krydstabulatorforespørgsel
Og især for "ekstra kolonner":
- Pivot på flere kolonner ved hjælp af Tablefunc
De særlige vanskeligheder her er:
-
Manglen på nøglenavne.
--> Vi erstatter medrow_number()
i en underforespørgsel. -
Det varierende antal e-mails.
--> Vi begrænser til max. af tre i den ydreSELECT
og brugcrosstab()
med to parametre, der giver en liste over mulige nøgler.
Vær opmærksom på NULLS LAST
i ORDER BY
.