Анализировать столбец JSON с циклом FOR для каждой записи? - PullRequest
0 голосов
/ 27 мая 2018

Будучи новичком в Postgres и SQL в целом, у меня есть следующий сценарий в Postgres 9.6:

table1

"Myjson" JSON
"DateOfAcquisition"  DATE
"Id" INT

В "Myjson" есть список, который яитерация по циклу FOR.

Моя цель - поместить элементы каждого списка json в table1 в другую таблицу:

table2

jsonelem1 INT
jsonelem2 INT
"DateOfAcquisition" DATE
"Id" INT

Я написал следующий код для разбора поля json, но я не уверен, как запустить цикл for для каждой записи первой таблицы.

    DO
$BODY$
DECLARE
    omgjson json := myjsonfield; -- this should change for every row of the first table
    i json;
    myJsonelem1 INT;
    myJsonelem2 INT;

begin

FOR i IN SELECT * FROM json_array_elements(omgjson)
  loop
    myJsonelem2 i->>  'jsonsubfield'::INT;

    INSERT INTO destinationTable VALUES (myJsonelem2,DateOfAcquisition);
END LOOP;

END;
$BODY$ language plpgsql

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Подход, основанный на множестве, обычно намного быстрее (и короче и менее подвержен ошибкам), чем зацикливание.

Использование настройки вашего ответ , который в значительной степени отличается от ответа на ваш вопрос.

INSERT INTO table2(myfield, data)  -- cleaner: explicit target columns
SELECT k."myField", j.i ->> 'data'
FROM   table1 k, json_array_elements(k."ScrapedJson" -> 'calendar_days') j(i)
WHERE  NOT k."HasBeenProcessed"
-- ORDER BY ???  -- you might want to order rows favorably?

Неявное LATERAL соединение является ключевой техникой здесь.

... FROM   table1 k, json_array_elements(...) ...

- это сокращение от:

... FROM   table1 k
    CROSS  JOIN LATERAL json_array_elements(...) ...

Очевидно, "ScrapedJson" -> 'calendar_days' - это массив JSON, а не «список», как вы написали в вопросе.

:

В сторонах

Сделайте себе одолжение и избегайтедвойные кавычки CaMeL-падежа в Postgres.Беспорядочная комбинация идентификаторов в кавычках и без кавычек в вашем вопросе и ответе только вводит в заблуждение.Я процитировал названия столбцов в вашем вопросе, чтобы несколько соответствовать вашему ответу.Мой постоянный совет: используйте только легальные, строчные, без кавычек имена.

Рассмотрите данныеДля большинства рабочих нагрузок введите jsonb вместо json.

0 голосов
/ 28 мая 2018

Спасибо Лоуренсу, вот решение для всех, кто заинтересован.

Интересно, есть ли лучший способ для этого?

DO
$BODY$
DECLARE
    i json;
    k RECORD;
    mydata INT;
begin

FOR k IN SELECT * from TABLE1 where "HasBeenProcessed" = FALSE
    LOOP  

            FOR i IN SELECT * FROM json_array_elements(k."ScrapedJson" -> 'calendar_days')
              LOOP

                mydata = i->> 'data';

                INSERT INTO "Table2" VALUES (k."myField",mydata);

            END LOOP;


end LOOP;


END;
$BODY$ language plpgsql
...