使用整数或浮点数作为值创建多键 JSON 对象

sud*_*udo 2 postgresql json

我有一个文本表和双精度类型。从中,我想构建一个如下所示的 JSON 对象:({"a": 1.0, "b": 1.2, "c": 3.4}编辑:澄清一下,键是表中的文本列,值是双精度列)。请注意,值周围没有引号,因为它们是浮点数,而不是 JSON 标准支持的字符串。

使用 Postgres 9.5。有一个json_build_object函数需要两个并行的文本数组并构建一个带有文本键和文本值的 JSON 对象......也适用于 NULL 值,null在 JSON 中将它们转换为(无引号)。所以我会得到{"a": "1.0", "b": "1.2", "c": "3.4"}。但是如果我想要整数或浮点值怎么办?它不会采用任何数字类型数组。

我现在通过创建自己的函数在 Python 中处理它来解决这个问题!有没有办法在不定义新函数的情况下做到这一点?

CREATE OR REPLACE FUNCTION json_build_object_float_values(keys TEXT[], vals DOUBLE PRECISION[]) RETURNS JSONB AS
$$
    assert len(keys) == len(vals)
    import json
    d = {}
    for i in range(len(keys)):
        d[keys[i]] = float(vals[i])
    return json.dumps(d)
$$
LANGUAGE 'plpython3u' IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

(请注意,如果您使用它,它会返回 JSONB,但您可以将其更改为 JSON)

编辑,这里是测试输入和预期输出:

CREATE TABLE test (str text, num double precision);
INSERT INTO test(str, num) VALUES ('a', 1.0);
INSERT INTO test(str, num) VALUES ('b', 2.3);
-- Here's my solution using my custom function...
SELECT json_build_object_float_values(array_agg(str), array_agg(num)) FROM test;
-- expected output: 
--  json_build_object_float_values
-- --------------------------------
--  {"a": 1.0, "b": 2.3}
-- (1 row)
Run Code Online (Sandbox Code Playgroud)

更简单的一种:

SELECT json_build_object_float_values(ARRAY['the', 'quick'], ARRAY[1, 3]);

 json_build_object_float_values
--------------------------------
 {"the": 1.0, "quick": 3.0}
(1 row)
Run Code Online (Sandbox Code Playgroud)

McN*_*ets 5

更新

根据您的示例数据和所需的结果,您可以使用json_object_agg Postgres 函数获得它。

CREATE TABLE test (str text, num double precision);
INSERT INTO test(str, num) VALUES ('a', 1.0);
INSERT INTO test(str, num) VALUES ('b', 2.3);
Run Code Online (Sandbox Code Playgroud)
select json_object_agg(str, num)
from test;
Run Code Online (Sandbox Code Playgroud)
| json_object_agg |
| :--------------------- |
| { "a" : 1, "b" : 2.3 } |

dbfiddle在这里

您可以使用row_to_json Postgres 函数。

create table foo(f1 int, f2 varchar(10), f3 float, f4 decimal(18,2));
insert into foo values (2, 'name', 2.345, 23.23);
Run Code Online (Sandbox Code Playgroud)
select row_to_json(f)
from   (select f1,f2,f3,f4 from foo) f;
Run Code Online (Sandbox Code Playgroud)
| row_to_json |
| :----------------------------------------- |
| {"f1":2,"f2":"name","f3":2.345,"f4":23.23} |

dbfiddle在这里