2015-06-09 3 views
2

У меня есть табличный тест с двумя столбцами A и B и создайте из него таблицы1 и таблицу2.Получите результат запроса sql как json

test   table1    table2 
A B   A count(A)  B count(B) A 
95 1   95 7   1  3  95 
5 11   5 2   11 2  5 
95 1       9  4  95 
95 9 
95 1 
95 9 
5 11 
95 9 
95 9 

Как получить результат, как:

{"node": [ 
    {"child": [ 
       {"value": 3, 
       "name": "1"}, 
       {"value": 4, 
       "name": "9"}], 
     "value": 7, 
     "name": "95"}, 
    {"child": [ 
      {"value": 2, 
       "name": "11"}], 
     "value": 2, 
     "name": "5"}], 
"name": "test", 
"value": 9} 

Первая I группы по колонке А и посчитать группы Name = "95", значение = 7 и имя = "5", значение = 2 , Для каждой группы я считаю также столбец B. Есть много функций json, но до сих пор я понятия не имею, как получить результат выше.

точно запрос должен быть похож на:

select row_to_json(t) from (select * , (select array_to_json(array_agg(row_to_json(u))) from (select * from table1 where table1.a=table2.a) as u) from table2) as t; 
+0

ваш JSON действительно не имеет никакого смысла в соответствии с вашими таблицами, вы можете объяснить немного больше о том, как вы хотите получить имена и значения? –

+0

Я редактирую свой стартовый пост, что я сделал, я подсчитываю A и хочу сохранить число «95» в переменной value = 7. Затем II рассчитывает для обеих групп («95» и «5») по B. – StellaMaris

+0

http://sqlfiddle.com/#!9/568307/3 это то, как вы получаете данные из своей базы данных, но idk, как это сделать в этом формате без использования прикладного уровня –

ответ

1

Вы можете сгенерировать правильный JSON с функцией plpgsql. Это не очень сложно, хотя иногда и немного утомительно. Проверьте этот (переименовывать tt к фактическому имени таблицы):

create or replace function test_to_json() 
returns json language plpgsql 
as $$ 
declare 
    rec1 record; 
    rec2 record; 
    res text; 
begin 
    res = '{"node": ['; 
    for rec1 in 
     select a, count(b) ct 
     from tt 
     group by 1 
    loop 
     res = format('%s{"child": [', res); 
     for rec2 in 
      select a, b, count(b) ct 
      from tt 
      where a = rec1.a 
      group by 1,2 
     loop 
      res = res || format('{"value": %s, "name": %s},', rec2.ct, rec2.b); 
     end loop; 
     res = rtrim(res, ','); 
     res = format('%s],"value": %s, "name": %s},', res, rec1.ct, rec1.a); 
    end loop; 
    res = rtrim(res, ','); 
    res = format('%s], "value": %s}', res, (select count(b) from tt)); 
    return res:: json; 
end $$; 

select test_to_json(); 
+0

Должно быть более простое решение. Предположим, что у нас есть эти две таблицы (http://sqlfiddle.com/#!9/568307/3). Тогда представляется возможным получить результат, который мне нужен, через функции row_to_json и array_to_json, если я понимаю следующие ссылки (http://stackoverflow.com/questions/21137237/postgres-nested-json-array-using-row-to- JSON) и (http://stackoverflow.com/questions/13227142/postgresql-9-2-row-to-json-with-nested-joins) – StellaMaris

+0

Нечто похожее на " выберите row_to_json (т) из ( \t выберите *, ( \t \t выберите array_to_json (array_agg (row_to_json (и))) из ( \t \t \t выберите * от table1 где table1.a = table2.a \t \t), как у \t) \t из таблицы2 \t) как t; ' – StellaMaris

1

Гадкий но работает и без plpgsql:

select json_build_object('node', json_agg(q3), 'name', 'test', 'value', (select count(1) from test)) 
from 
(select json_agg(q2) from 
    (select a as name, sum(value) as value, json_agg(json_build_object('name', q1.name, 'value', q1.value)) as child 
    from 
     (select a, b as name, count(1) as value from test group by 1, 2) as q1 
    group by 1) as q2 
) as q3; 
+0

А какой путь проще? Поздравления :) – klin