如何将PostgreSQL JSON格式化和查询到sql中的n列行

时间:2017-12-05 16:10:23

标签: sql json postgresql

我想使用json并能够将其显示为三列列,如下所示。

scores median sigma
------ ------ -----
BF2D   0.5    0.67
BF2DSL 0.6    0.89

首先,我很难对其进行格式化。 第二,什么是适合的格式,以便我可以将它显示为三列列。有一种感觉,我应该使用数组表示? json_to_record(json)函数对我的用例来说似乎很有趣,但我需要帮助。

SELECT * from json_to_record('{"version": "1.0", "BF2D": [{"median": 0.5}, {"sigma": 0.67}], "BF2DSL": [{"median": 0.6}, {"sigma": 0.89}]}'::JSON) as x(median FLOAT, sigma FLOAT);

 median | sigma
--------+--------
 (NULL) | (NULL)

Not what i am looking for

我尝试使用嵌套数组,但无法将其格式化为json

SELECT '{"version": "1.0", "scores": [{ "BF2D": [{"median": 0.5}, {"sigma": 0.67}] }, { "BF2DSL": [{"median": 0.6}, {"sigma": 0.89}] }]'::JSON;

1 个答案:

答案 0 :(得分:0)

知道了!

我们可以按如下方式检索基本级别键:

SELECT * FROM json_object_keys('{"version": "1.0", "BF2D": {"avg": 0.5, "max": 99}, "BF2DSL": {"avg": 0.9, "max": 67}}'::JSON) scores WHERE scores<>'version';
 scores
--------
 BF2D
 BF2DSL

我们可以获取特定基本级别密钥的密钥/值,例如,对于BF2D,如下所示

SELECT * FROM json_each('{"version": "1.0", "BF2D": {"avg": 0.5, "max": 99}, "BF2DSL": {"avg": 0.9, "max": 67}}'::JSON->'BF2D');
 KEY | value
-----+-------
 avg | 0.5
 max | 99

但是,不能使用上面两个查询来获得3列行

SELECT scores, json_each('{"version": "1.0", "BF2D": {"avg": 0.5, "max": 99}, "BF2DSL": {"avg": 0.9, "max": 67}}'::JSON->scores)
FROM (SELECT * FROM json_object_keys('{"version": "1.0", "BF2D": {"avg": 0.5, "max": 99}, "BF2DSL": {"avg": 0.9, "max": 67}}'::JSON) scores WHERE scores<>'version') t;
 scores | json_each
--------+-----------
 BF2D   | (avg,0.5)
 BF2D   | (max,99)
 BF2DSL | (avg,0.9)
 BF2DSL | (max,67)

最后,我们可以将结果显示在单独的列中,如下所示

WITH p AS
  (SELECT '{"version": "1.0", "BF2D": {"avg": 0.5, "max": 99, "sigma": 0.1}, "BF2DSL": {"avg": 0.9, "max": 67}}'::JSON AS jval),
t AS
  (SELECT jval,json_object_keys(jval) cod FROM p),
scores AS
  (SELECT * FROM t WHERE cod<>'version')
SELECT cod,t.* FROM scores,json_each(jval->cod) t;

  cod   |  key  | value
--------+-------+-------
 BF2D   | avg   | 0.5
 BF2D   | max   | 99
 BF2D   | sigma | 0.1
 BF2DSL | avg   | 0.9
 BF2DSL | max   | 67