我有下表,为每个用户提供多个电子邮件地址。
我需要将其展开为用户查询的列。根据创建日期给我“最新”3个电子邮件地址。
user.name | user.id | email1 | email2 | email3** Mary | 123 | mary@gmail.com | mary@yahoo.co.uk | mary@test.com Joe | 345 | joe@gmail.com | [NULL] | [NULL]
解决方法
使用
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);
我用美元引用第一个参数,这没有什么特别的意义。如果您必须在查询字符串中转义单引号,这是一个常见的情况,那就很方便:
> Insert text with single quotes in PostgreSQL
详细说明和说明:
特别是“额外列”:
> Pivot on Multiple Columns using Tablefunc
这里的特殊困难是:
>缺少关键名字。
– >我们用row_number()
替代子查询。
>不同数量的电子邮件。
– >我们限制在最大的三个在外部的SELECT
并使用具有两个参数的crosstab(),提供可能的键的列表。