sql - PostgreSQL - 返回键值对数组的最佳方式

标签 sql database postgresql npgsql

我正在尝试选择多个字段,其中一个字段必须是一个数组,该数组的每个元素都包含两个 值。每个数组项都需要包含一个名称(字符不同)和一个 ID(数字)。我知道如何返回单个值的数组(使用 ARRAY 关键字)但我不确定如何返回本身包含两个值的对象的数组。

查询是这样的

SELECT
    t.field1,
    t.field2,
    ARRAY(--with each element containing two values i.e. {'TheName', 1 })
FROM MyTable t

我读到,一种方法是将值选择为一种类型,然后创建该类型的数组。问题是,函数的其余部分已经返回一个类型(这意味着我将拥有嵌套类型 - 可以吗?如果是这样,您将如何在应用程序代码中读回这些数据 - 即使用像 NPGSQL 这样的 .Net 数据提供程序?)

非常感谢任何帮助。

最佳答案

ARRAY 只能容纳相同类型的元素

您的示例显示一个 text 和一个 integer 值(1 周围没有单引号)。通常不可能在数组中混合类型。要将这些值放入数组中,您必须创建一个复合类型,然后像您自己提到的那样形成该复合类型的 ARRAY。

或者您可以使用数据类型 json在 Postgres 9.2+ 中,jsonb 在 Postgres 9.4+ 中或 hstore对于键值对。


当然,您可以将integer 转换为text,并使用二维文本数组。考虑下面演示中数组输入的两种语法变体并引用 the manual on array input .

有一个限制需要克服。如果您尝试将 ARRAY(从键和值构建)聚合到二维数组中,聚合函数 array_agg()ARRAY 构造函数会出错:

ERROR:  could not find array type for data type text[]

不过,还是有办法解决的。

将键值对聚合成一个二维数组

PostgreSQL 9.1 standard_conforming_strings= on :

CREATE TEMP TABLE tbl(
 id     int
,txt    text
,txtarr text[]
);

txtarr 只是为了演示 INSERT 命令中的语法变体。第三行带有元字符:

INSERT INTO tbl VALUES
 (1, 'foo', '{{1,foo1},{2,bar1},{3,baz1}}')
,(2, 'bar', ARRAY[['1','foo2'],['2','bar2'],['3','baz2']])
,(3, '}b",a{r''', '{{1,foo3},{2,bar3},{3,baz3}}'); -- txt has meta-characters

SELECT * FROM tbl;

简单情况:将两个整数(我用了两次相同)聚合成一个二维int数组:

更新:更好地使用自定义聚合函数

随着polymorphic type anyarray它适用于所有基本类型:

CREATE AGGREGATE array_agg_mult (anyarray)  (
    SFUNC     = array_cat
   ,STYPE     = anyarray
   ,INITCOND  = '{}'
);

调用:

SELECT array_agg_mult(ARRAY[ARRAY[id,id]]) AS x        -- for int
      ,array_agg_mult(ARRAY[ARRAY[id::text,txt]]) AS y -- or text
FROM   tbl;

注意额外的 ARRAY[] 层使其成为多维数组。

Postgres 9.5+ 更新

Postgres 现在提供了一个接受数组输入的 array_agg() 变体,你可以用这个替换我上面的自定义函数:

The manual:

array_agg(expression)
...
input arrays concatenated into array of one higher dimension (inputs must all have same dimensionality, and cannot be empty or NULL)

关于sql - PostgreSQL - 返回键值对数组的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9129855/

相关文章:

python - mysql 未连接到数据库

sql - 在 PL/SQL 中检查空值的正确方法是什么?

具有多个条件的 SQL 查询 group by

mysql - 通过 mySQL 命令行直接上传图片

mysql - 加快返回许多结果的 mysql 查询

sql - 我棘手的 SQL 更新查询效果不佳

arrays - 将自定义类型的数组从node-pg和SQL注入(inject)传递给postgres函数

SQL 查询从多个表中获取不同的行

sql - 单独查询计数

mysql - 找到一对参加完全相同类(class)的学生