下表给出了每个用户的多个邮箱地址.

在此处输入图像描述

我需要在用户查询中将其平铺为列.根据创建日期给我"最新"的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模块中的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);

我对第一个参数使用了美元报价,它没有特殊意义.在查询字符串中转义单引号很方便,这是一种常见情况:

详细解释和说明:

特别是对于"额外列":

这里的special difficulties个是:

  • The lack of key names.
    --> We substitute with row_number() in a subquery.

  • The varying number of emails.
    --> We limit to a max. of three in the outer SELECT
    and use crosstab() with two parameters, providing a list of possible keys.

注意NULLS LAST in the ORDER BY.

Sql相关问答推荐

Postgresql:从jsons数组到单个id索引的json

如何实现一个广泛的多级自连接PostgreSQL查询?

Select 起始参数和截止参数之间的间隔,包括与期间重叠的参数

如何使用WSO2将空值传递给我的SQL Server存储过程?

按每天的最大值分组

替换上一个或下一个值中的空值并添加其价格日期

为什么TRY_CONVERT返回一个XML验证错误而不是NULL?

使用SQL数据库中的现有列派生或修改几个列

其中使用表名作为;行值;记录?

从每月生成的系列中生成每日汇率

当 ansible 变量未定义或为空时,跳过 sql.j2 模板中的 DELETE FROM 查询

SQL 语句将一列中的值与另一列中的不同值相加,同时按第三列进行分组?

SQL的左连接在多对多关系情况下使用

oracle中多行的跨日期范围的交集

函数调用作为插入值语句中的参数

如何根据与 BigQuery 中另一个表的匹配更新一个表中的列?

如何获得上个月和下个月之间的销售额差异

BigQuery - 将 TIMESTAMP 转换为 HH:MM:SS,然后识别 TIME_DIFF

奇怪的甲骨文行为

使用 SQL 表中的连接列删除重复记录