2017-01-05 2 views
0

У меня есть столбец, содержащий объект json. Моя цель - получить общее количество массива, даже если я использую лимит.Postgres get json count over

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 

Это показывает первую строку, но мне кажется, что счет более() не принимается во внимание, на самом деле я получаю только 1 вместо 3

Есть еще один способ сделать это?

ответ

1

Вы должны использовать правильный боковой присоединиться, чтобы сделать эту работу:

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

Это одна из причин, почему набор функции, возвращающие не следует назвать в select списке.

Другой вариант, который, вероятно, быстрее, заключается в использовании json_array_length(), который был введен в Postgres 9,3

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; 
+0

отличный ответ, но json_array_length действительно доступен на версиях 9.3+ –

1

Место json_array_elements() в FROM пункте:

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

count 
------- 
    3 
(1 row) 
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 

Я не вижу, почему в этой ситуации требуется функция перекрестного соединения или окна, хотя с ними можно получить один и тот же результат.