【问题标题】:Split column into multiple rows in Postgres在 Postgres 中将列拆分为多行
【发布时间】:2015-06-07 19:46:12
【问题描述】:

假设我有这样一张桌子:

    subject     | flag
----------------+------
 this is a test |    2

subjecttext 类型,flagint 类型。我想在 Postgres 中将此表转换为类似的东西:

    token       | flag
----------------+------
 this           |    2
 is             |    2
 a              |    2
 test           |    2

有没有简单的方法可以做到这一点?

【问题讨论】:

    标签: sql postgresql split set-returning-functions


    【解决方案1】:

    在 Postgres 9.3+ 中使用 LATERAL 加入:

    SELECT s.token, flag
    FROM   tbl t, unnest(string_to_array(t.subject, ' ')) s(token)
    WHERE  flag = 2;
    

    这是一个隐含的LATERAL 加入。如果unnest() 不返回任何行(空或NULL subject),则结果将根本没有行。使用LEFT JOIN unnest(...) i ON true 始终从tbl 返回行。见:

    您也可以使用regexp_split_to_table(),但这通常会更慢,因为正则表达式匹配的成本更高。相关:

    【讨论】:

    • 我对@9​​87654333@ join 或unnest() 函数都不是很熟悉。您如何将其表达为横向连接?
    • @Manngo:这一个横向连接,只是语法简短。详细等效:SELECT * FROM tbl t CROSS JOIN LATERAL unnest(string_to_array(t.subject, ' ')) AS s(token); 链接答案中的充分解释。
    • 谢谢。我一直将… , … 语法理解为简单的交叉连接。
    • 对于函数,自动为cross join lateral
    【解决方案2】:

    我认为没有必要使用连接,只需将 unnest() 函数与 string_to_array() 结合使用即可:

    SELECT unnest(string_to_array(subject, ' ')) as "token", flag FROM test;
    
    token | flag                                                                                                   
    -------+-------                                                                                                  
    this   |     2                                                                                                   
    is     |     2                                                                                                   
    a      |     2                                                                                                   
    test   |     2                                                                                                   
    

    【讨论】:

    • 有效。 SELECT 中的集合返回函数相当于相关子查询。细微的差异:返回行,即使unnest() 没有返回行 - 转换为NULL。可能是可取的,也可能不是可取的。此外,还有一些其他注意事项适用。见:stackoverflow.com/a/28557803/939860
    【解决方案3】:

    使用正则表达式拆分到表功能,包括横向连接,

    SELECT s.token, flag
    FROM   tbl t, regexp_split_to_table(t.subject, ' ') s(token)
    WHERE  flag = 2;
    

    参考https://www.postgresql.org/docs/9.3/functions-string.html 功能详情

    【讨论】:

      猜你喜欢
      • 2021-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多