Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PostgreSQL中将行强制转换为数组_Postgresql - Fatal编程技术网

在PostgreSQL中将行强制转换为数组

在PostgreSQL中将行强制转换为数组,postgresql,Postgresql,我需要查询表,如中所示 SELECT * FROM table_schema.table_name 只有每一行需要是一个文本[],其数组值对应于列值,这些列值以与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

我需要查询表,如中所示

SELECT *
FROM table_schema.table_name
只有每一行需要是一个文本[],其数组值对应于列值,这些列值以与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
只是它不应该按名称显式列出列。理想情况下,它应该看起来像

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
我想出的最好的版本看起来很难看,而且依赖于hstore扩展

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

另一个查询获得了与第一个查询相同的结果,但可以说与第一个查询一样丑陋和低效,它的灵感来自。它可能效率更低,但不依赖于扩展

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个选项

使用JSON。它不依赖于任何扩展,它写起来很短,易于理解,速度还可以。 使用hstore。在100K数据集上,此替代方法的速度比JSON方法快10倍以上,但需要扩展。hstore通常是非常方便的扩展。 使用正则表达式解析行的文本表示形式。这个选择真的很慢。
我能想到的最简单的读取方法是首先转换为字符串,然后将该字符串解析为数组。像这样:

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

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

我能想到的最简单的读取方法是首先转换为字符串,然后将该字符串解析为数组。像这样:

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

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

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

select array(select (json_each_text(to_json(t))).value) as row_value
from some_table t
这在某种程度上与你的hstore黑客行为相同

如果列的顺序很重要,那么可以使用json和有序性来保持:

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

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

select array(select (json_each_text(to_json(t))).value) as row_value
from some_table t
这在某种程度上与你的hstore黑客行为相同

如果列的顺序很重要,那么可以使用json和有序性来保持:

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

如果不按名称列出列,则无法确定它们在结果数组中的顺序。@Schwern当然可以:我的丑陋示例已经做到了这一点。下面bspates的另一种笨拙的方法也可以实现这一点:它使用表中定义的顺序。如果这改变了,数组中的顺序也会改变。有这么多的列,你不想键入它们,这通常意味着需要重新设计架构。@Schwern这与以统一的方式处理任意查询的结果有关,而不是懒于键入列名:dwy你为什么不直接使用jsonb将行转换为单个值?然后,您还可以获得列名,而不管查询是什么。如果您不按名称列出列,则无法确定它们在结果数组中的顺序。@Schwern当然可以:我的丑陋示例已经做到了这一点。下面bspates的另一种笨拙的方法也可以实现这一点:它使用表中定义的顺序。如果这改变了,数组中的顺序也会改变。有这么多的列,你不想键入它们,这通常意味着需要重新设计架构。@Schwern这与以统一的方式处理任意查询的结果有关,而不是懒于键入列名:dwy你为什么不直接使用jsonb将行转换为单个值?然后,您也可以获得列名,而不管查询是什么。这可能有效,但只有在值中没有逗号时才有效。这可能有效,但只有在值中没有逗号时才有效。json键/值没有内在顺序,因此您无法保证它的顺序与SELECT*@bspates相同:当改用json时,如果这很重要,可以保留列的顺序接受它作为答案,虽然这不是我希望的答案,但与我的不同,它不依赖于扩展。我认为行到数组的转换可能更简单:json键/值没有内在顺序,因此在使用json时无法保证其顺序与SELECT*@bspates:相同,如果这很重要,可以保留列的顺序接受它作为答案,虽然这不是我希望的答案,但与我的不同,它不依赖于扩展。我认为行到数组的转换可能更简单: