Postgres让json算过来

时间:2017-01-05 11:24:25

标签: json postgresql window-functions

我有一个包含json对象的列。我的目标是获得阵列的总数,即使我使用限制。

CREATE TABLE json_values (
   elems json
);

INSERT INTO json_values VALUES ('{"field1" : [{"val" : 1}, {"val" : 2}, { "val" : 3}] ,"field2" : []}');


SELECT json_array_elements(elems->'field1'), count(*) OVER()
FROM json_values
LIMIT 1

这显示第一行,但似乎没有考虑计数over(),实际上我只得到1而不是3。

还有其他办法吗?

3 个答案:

答案 0 :(得分:1)

你需要使用适当的横向连接来完成这项工作:

SELECT e.*, count(*) OVER()
FROM json_values
  cross join lateral json_array_elements(elems->'field1') as e(val)
LIMIT 1;

这是不应在select列表中调用set return函数的原因之一。

另一种可能更快的选择是使用Postgres 9.3中引入的json_array_length()

SELECT e.*, json_array_length(elems->'field1')
FROM json_values 
  cross join lateral json_array_elements(elems->'field1') as e (val)
LIMIT 1;

根据您想要做什么,在进行交叉连接之前限制可能的数组元素可能会更有效:

select e.*, json_array_length(elems->'field1')
from json_values 
  cross join lateral (
    select * 
    from json_array_elements(elems->'field1')
    limit 1
  )  as e (val)

但是如果你只想为每个文档获取数组的第一个元素,那么下面会更快:

SELECT (elems->'field1') -> 0, json_array_length(elems->'field1')
FROM json_values;

答案 1 :(得分:1)

json_array_elements()放在FROM子句中:

select count(*) over()
from json_values, 
lateral json_array_elements(elems->'field1')
limit 1;

 count 
-------
     3
(1 row) 

答案 2 :(得分:1)

有一个函数可以返回json数组的长度:

https://www.postgresql.org/docs/9.3/static/functions-json.html

SELECT 
    json_array_elements(elems->'field1') field1
  , json_array_length(elems->'field1') field_1_length
FROM json_values
LIMIT 1

我不明白为什么在这种情况下需要交叉连接或窗口功能,尽管可以使用它们获得相同的结果。