代码之家  ›  专栏  ›  技术社区  ›  oᴉɹǝɥɔ

在PostgreSQL中将行转换为数组

  •  0
  • oᴉɹǝɥɔ  · 技术社区  · 7 年前

    SELECT *
    FROM table_schema.table_name
    

    只有每一行需要是 TEXT[] TEXT 以与之相同的顺序出现 SELECT * a , b c 我需要结果看起来像

    SELECT ARRAY[a::TEXT, b::TEXT, c::TEXT]
    FROM table_schema.table_name
    

    只是它不应该按名称显式列出列。理想情况下它应该看起来像

    SELECT as_text_array(a)
    FROM table_schema.table_name AS a
    

    WITH columnz AS ( -- get ordered column name array
        SELECT array_agg(attname::TEXT ORDER BY attnum) AS column_name_array
        FROM pg_attribute
        WHERE attrelid = 'table_schema.table_name'::regclass AND attnum > 0 AND NOT attisdropped
    )
    SELECT hstore(a)->(SELECT column_name_array FROM columnz)
    FROM table_schema.table_name AS a
    

    我觉得必须有一个更简单的方法来实现这一点

    更新1

    另一个查询的结果与第一个查询相同,但可以说它和第一个查询一样丑陋和低效 @bspates . 它的效率可能更低,但不依赖于扩展

    SELECT r.text_array
    FROM table_schema.table_name AS a
        INNER JOIN LATERAL ( -- parse ROW::TEXT presentation of a row
            SELECT array_agg(COALESCE(replace(val[1], '""', '"'), NULLIF(val[2], ''))) AS text_array
            FROM regexp_matches(a::text, -- parse double-quoted and simple values separated by commas
                '(?<=\A\(|,)  (?:  "(  (?:[^"]|"")*  )"  |  ([^,"]*)  )  (?=,|\)\Z)', 'xg') AS t(val)
        ) AS r ON TRUE
    

    这还远远不够理想

    更新2

    我测试了目前存在的3个选项

    1. 使用 JSON
    2. 使用 hstore JSON格式 方法,但需要扩展。 总的来说是非常方便的扩展。
    3. 使用 regex 解析行的文本表示。这个选择很慢。
    0 回复  |  直到 7 年前
        1
  •  2
  •   a_horse_with_no_name    7 年前

    一种有点难看的方法是将行转换为JSON值,然后取消对值的测试并将其聚合回数组:

    select array(select (json_each_text(to_json(t))).value) as row_value
    from some_table t
    

    如果列的顺序很重要,则使用 json with ordinality 可以用来保存:

    select array(select val 
                 from json_each_text(to_json(t)) with ordinality as t(k,val,idx) 
                 order by idx)
    from the_table t
    
        2
  •  0
  •   bspates    7 年前

    我能想到的最简单的(read hacky est)方法是先转换为字符串,然后将该字符串解析为数组。是这样的:

    SELECT string_to_array(table_name::text, ',') FROM table_name
    

    但根据表中数据的大小和类型,这可能会执行得非常糟糕。