2016-01-18 3 views
2

Итак, у меня есть две таблицы, одна из которых содержит фиксированную часть каждого объекта, а другая содержит переменное количество свойств каждого объекта в качестве пар ключ/значение. Я хотел бы преобразовать эти свойства в поле CLOB в основной таблице в формате карты JSON.Агрегация в SQL-запросе UPDATE

create table test_a (id integer, properties clob); 
create table test_b (id integer, a_id integer, key char(30), value char(30)); 

insert into test_a values(1,''); 
insert into test_a values(2,''); 
insert into test_a values(3,''); 

insert into test_b values (1, 1, 'k1', 'v1'); 
insert into test_b values (2, 1, 'k2', 'v2'); 
insert into test_b values (3, 2, 'k3', 'v3'); 
insert into test_b values (4, 2, 'k4', 'v4'); 
insert into test_b values (5, 2, 'k5', 'v5'); 
insert into test_b values (6, 2, 'k6', 'v6'); 

Я могу построить JSON Я хочу, чтобы с помощью следующего запроса:

WITH PROPS AS 
    (SELECT '"' 
    ||trim(KEY) 
    ||'":"' 
    ||trim(value) 
    ||'"' json, 
    test_b.* 
    FROM test_b 
) 
SELECT test_a.id, 
    '{' 
    || 
    (SELECT listagg(json, ',') within GROUP (
    ORDER BY props.key) 
    FROM PROPS 
    WHERE PROPS.A_ID = test_a.id 
) 
    || '}' 
FROM TEST_A 
INNER JOIN PROPS 
ON TEST_A.ID = PROPS.A_ID 
GROUP BY TEST_A.ID ; 

И получить желаемый результат

1 "{""k1"":""v1"",""k2"":""v2""}" 
2 "{""k3"":""v3"",""k4"":""v4"",""k5"":""v5"",""k6"":""v6""}" 

Но когда я пытаюсь использовать этот результат для вставки в главный стол, я получаю ошибки

UPDATE TEST_A SET PROPERTIES = (
WITH PROPS AS 
    (SELECT '"' 
    ||trim(key) 
    ||'":"' 
    ||trim(value) 
    ||'"' json, 
    test_b.* 
    FROM test_b 
) 
SELECT '{' 
    || 
    (SELECT listagg(json, ',') within GROUP (order by props.key) FROM PROPS 
    WHERE PROPS.A_ID = test_a.id) 
    || '}' from TEST_A INNER JOIN PROPS ON TEST_A.ID = PROPS.A_ID GROUP BY TEST_A.ID 
) ; 

Error report - 
SQL Error: ORA-01427: single-row subquery returns more than one row 
01427. 00000 - "single-row subquery returns more than one row" 

Любые идеи?

ответ

2

Вам нужен коррелированный подзапрос, а не group by. Весь внешний запрос выглядит не так, поэтому я думаю, что вам нужно что-то вроде:

UPDATE TEST_A 
    SET PROPERTIES = (
     WITH PROPS AS (
       SELECT '"'||trim(key)||'":"'||trim(value)||'"' as json, 
        test_b.* 
       FROM test_b 
      ) 
     SELECT '{' || listagg(json, ',') within GROUP (order by props.key) || '}' 
     FROM PROPS 
     WHERE PROPS.A_ID = test_a.id 
     ) ; 
+0

Фантастический, работает как шарм – user2650994