我有下表,其中为每个用户提供了多个电子邮件地址。
我需要将其展平为用户查询的列。根据创建日期向我提供“最新”的 3 个电子邮件地址。喜欢:
用户名 | 用户ID | 电子邮件1 | 电子邮件2 | 电子邮件3 |
---|---|---|---|---|
玛丽 | 123 | 玛丽@gmail.com | 玛丽@yahoo.co.uk | [email protected] |
乔 | 345 | [email protected] | [空] | [空] |
使用
tablefunc模块中的
crosstab()
。
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);
我对第一个参数使用了美元引号,它没有特殊含义。在查询字符串中转义单引号很方便,这是常见的情况:
详细解释和说明:
特别是对于“额外的列”:
这里的特殊困难是:
row_number()
。
电子邮件数量不同。
→ 我们限制最大。外部
SELECT
中的三个,并使用 crosstab()
和两个参数,提供可能的键列表。
NULLS LAST
中的ORDER BY
。