使用PostgreSQL在SQL查询中创建空数组,而不是内部为NULL的数组

使用PostgreSQL在SQL查询中创建空数组,而不是内部为NULL的数组,sql,arrays,postgresql,Sql,Arrays,Postgresql,我正在使用以下模式: CREATE TABLE person ( person_name VARCHAR PRIMARY KEY ); CREATE TABLE pet ( animal_name VARCHAR, person_name VARCHAR REFERENCES person(person_name), PRIMARY KEY (animal_name, person_name) ); 我希望创建一个表,其中,对于每个人名,我将获得一个包含该人宠物的数组。我正在

我正在使用以下模式:

CREATE TABLE person (
  person_name VARCHAR PRIMARY KEY
);

CREATE TABLE pet (
  animal_name VARCHAR,
  person_name VARCHAR REFERENCES person(person_name),
  PRIMARY KEY (animal_name, person_name)
);
我希望创建一个表,其中,对于每个
人名
,我将获得一个包含该人宠物的数组。我正在使用PostgreSQL 9.3.4

我在每个表中都有以下值:

PERSON_NAME
-----------
Alice
Bob
宠物

ANIMAL_NAME | PERSON_NAME
-------------------------
Woof        | Alice
Meow        | Alice
我希望创建下表:

PERSON_NAME | PETS
--------------------------
Alice       | {Woof, Meow}
Bob         | {}
但是,我无法创建空数组。我得到的是:

PERSON_NAME | PETS
--------------------------
Alice       | {Woof, Meow}
Bob         | {NULL}
这是我正在使用的查询:

SELECT
  person.person_name,
  array_agg(pet.animal_name) AS pets
FROM
  person LEFT JOIN pet ON person.person_name = pet.person_name
GROUP BY
  person.person_name
;
我明白为什么我得到的数组里面有
NULL
值,我想知道如何得到一个空数组

下面是一个示例,其中包含创建模式、插入值和使用的查询所需的代码。网站中显示的结果没有显示
NULL
值,尽管它存在

编辑


结果将被解析为JSON,这就是为什么
{NULL}
不是可接受的结果,因为它将被解析为
[NULL]
,这与我需要的
[]
不同。出于同样的原因,类似于
{”“}
的结果也是不可接受的。

您可以使用
合并
替换
空值
值:

SELECT
  person.person_name,
  array_agg(coalesce(pet.animal_name,'')) AS pets
FROM
  person LEFT JOIN pet ON person.person_name = pet.person_name
GROUP BY
  person.person_name
;

我想到了两种可能性

一个选择是联合

select person.person_name, array_agg(pet.animal_name) as pets
from person
join pet on person.person_name = pet.person_name
group by person.person_name

union

select person.person_name, array[]::text[] as pets
from person
left join pet on person.person_name = pet.person_name
where pet.animal_name is null
第一部分使用连接来获得有宠物的人,然后第二部分抓住那些根本没有宠物的穷人。分离它们可以为没有宠物的人提供一个文本空数组

另一种选择是使用派生表的左连接执行几乎相同的操作:

with pet_names as (
  select person.person_name, array_agg(pet.animal_name) as pets
  from person
  join pet on person.person_name = pet.person_name
  group by person.person_name
)
select p.person_name, coalesce(n.pets, array[]::text[])
from person p
left join pet_names n on p.person_name = n.person_name
这对我来说更自然一些,因为它允许您使用COALESCE(您想要将NULL映射到其他对象的第一件事情)来提供空数组

更新的演示:


可能还有其他解决方案,这两种方法对我来说似乎是很自然的方法。

最简单的方法是使用:


我只想补充一点,这已经6岁了

数组[]:::varchar[]


这给了我
{”“}
而不是
{}
。我相信它们不一样。@9lo--除了
NULL
和空字符串之外,我不知道还有其他值。您可能在谈论表示逻辑而不是sql。这是上述查询的结果——通过终端在psql中检查结果。我确实说过fiddle中显示的结果不会打印
NULL
值。查询得到的结果将被解析为JSON,其中
[]!=[null]
以及
[]!=[“”]
。我很抱歉更改了公认的答案,但是@pozs的答案看起来更干净。
SELECT
  person.person_name,
  ARRAY(SELECT animal_name FROM pet WHERE person.person_name = pet.person_name) AS pets
FROM
  person;