Använd crosstab()
från tablefunc-modulen.
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);
Jag använde dollarnotering för den första parametern, som inte har någon speciell betydelse. Det är bara bekvämt att undvika enstaka citattecken i frågesträngen, vilket är ett vanligt fall:
- Infoga text med enkla citattecken i PostgreSQL
Detaljerad förklaring och instruktioner:
- PostgreSQL Crosstab Query
Och i synnerhet för "extra kolumner":
- Pivota på flera kolumner med Tablefunc
De särskilda svårigheterna här är:
-
Bristen på nyckelnamn.
--> Vi ersätter medrow_number()
i en underfråga. -
Det varierande antalet e-postmeddelanden.
--> Vi begränsar till ett max. av tre i den yttreSELECT
och användcrosstab()
med två parametrar, vilket ger en lista över möjliga nycklar.
Var uppmärksam på NULLS LAST
i ORDER BY
.