json - 如何将 array_agg/array_to_json 应用于具有修改列的查询

标签 json postgresql

我将 array_to_jsonarray_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 出现空值。我宁愿看到字符串“User logged in from $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 调用类型构造函数,这返回了相同的错误。该错误对我来说没有意义 - 如果子查询是聚合的,那么它是否返回多列无关紧要。有什么建议吗?

最佳答案

您可以将聚合调用与子查询分开并使用 row用于生成复合数据的构造函数:

SELECT 
    array_to_json(array_agg(row(t.*))) AS users 
FROM 
    (
        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
    ) t
;

您也可以在 SQLFiddle 上查看.

关于json - 如何将 array_agg/array_to_json 应用于具有修改列的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13819197/

相关文章:

订阅 PostgreSQL/MySql 的 Java 应用程序

perl - 允许 unix 用户 'postgres' 访问 plperlu 的外部 .pm 文件

sql - 索引扫描期间命中+读取的缓冲区过多

java - 使用 Gson 反序列化有时是字符串有时是对象

php - 通过 POST 将 JSON 编码的变量从 PHP 传递到 Javascript

json - Aurelia aurelia-fetch-client 和 JSON POST

ruby-on-rails - JBuilder中未定义的局部变量或方法 `json'

json - 使用 AngularJS 解析带有数组的 JSON 文件

postgresql - 如何避免 0(零)int 变成 Postgres "null"值并违反 "not null"约束?

sql-server - 描述 PostgreSQL 中的结果集?