我array_to_json
结合使用array_agg
将 PostgreSQL 中的某些结果格式化为 JSON。当我想返回查询的默认值(所有列,未修改)时,这适用于查询。但我很难过如何使用array_agg
为要修改某些输出的查询创建 JSON 对象。
这是一个例子:
CREATE TABLE temp_user (
user_id serial PRIMARY KEY,
real_name text
);
CREATE TABLE temp_user_ip (
user_id integer,
ip_address text
);
INSERT INTO temp_user (user_id, real_name) VALUES (1, 'Elise'), (2, 'John'), (3, NULL);
INSERT INTO temp_user_ip (user_id, ip_address) VALUES (1, '10.0.0.4'), (2, '10.0.0.7'), (3, '10.0.0.9');
以下查询工作正常:
# SELECT array_to_json(array_agg(temp_user)) as users from temp_user;
users
-----------------------------------------------------------------------------------------------------
[{"user_id":1,"real_name":"Elise"},{"user_id":2,"real_name":"John"},{"user_id":3,"real_name":null}]
但是假设我不喜欢为用户 3 出现的空值。我宁愿看到字符串“用户从 $ip 登录”。
我可以做这个:
# SELECT user_id, (CASE WHEN real_name IS NULL THEN (select 'User logged in from ' || ip_address FROM temp_user_ip WHERE user_id = temp_user.user_id) ELSE real_name END) as name from temp_user;
我得到以下结果:
user_id | name
---------+------------------------------
1 | Elise
2 | John
3 | User logged in from 10.0.0.9
这是伟大的。但我不知道如何像第一个示例那样将这些数据操作为 JSON 格式。
所需的输出是:
[{"user_id":1,"name":"Elise"},{"user_id":2,"name":"John"},{"user_id":3,"name":"User logged in from 10.0.0.9"}]
这不起作用:
# select array_to_json(array_agg ( (SELECT user_id, (CASE WHEN real_name IS NULL THEN (select 'User logged in from ' || ip_address FROM temp_user_ip WHERE user_id = temp_user.user_id) ELSE real_name END) as name from temp_user)));
ERROR: subquery must return only one column
我想不出任何方法将数据转换为array_agg
可接受的格式。我什至尝试创建一个与 temp_user 格式匹配的自定义类型,并尝试array_agg
调用类型构造函数,它返回了相同的错误。这个错误对我来说没有意义——如果子查询是聚合的,那么它是否返回多于一列就无关紧要了。有什么建议吗?