【问题标题】:Postgres - Transpose Rows to ColumnsPostgres - 将行转置为列
【发布时间】:2023-03-27 07:52:01
【问题描述】:

我有下表,它为每个用户提供了多个电子邮件地址。

我需要将其展平为用户查询的列。根据创建日期为我提供“最新”的 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]

【问题讨论】:

    标签: sql database postgresql crosstab transpose


    【解决方案1】:

    使用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 in the ORDER BY

    【讨论】:

    • 完美,谢谢。正是我需要的。这个查询可能有点超出我的理解,但帮助我学习和理解了很多。
    • 对于那些想知道的人。不,这在 AWS Redshift 上不起作用。
    • @MarcelloGrechiLins:这个问答是针对 Postgres,而不是 Redshift。
    • @ErwinBrandstetter 我知道,但由于 Redshift 使用“Postgre Compliant”驱动程序,大多数寻找问题答案的 Redshift 用户会搜索“PostgreSQL”,因为社区更大,如果找到回答您的 Redshift 问题,在 Postgre 帖子上更高 :) 希望这是有道理的
    • @MarcelloGrechiLins:Redshift 是一个基于 Postgres 8.0.2 的分支,list of unsupported Postgres features 已经成长了很长时间。顺便说一句,it's PostgreSQL or Postgres, never "Postgre"。这就像在说 "Redshif"
    猜你喜欢
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多