Преобразовать два столбца в строку JSON пары ключ-значение в Presto - PullRequest
0 голосов
/ 28 июня 2018

Учитывая это:

XXX YYY ZZZ
--- --- ---
AAA PPP LLL
AAA QQQ MMM
AAA RRR NNN

Как мне преобразовать это в это?

XXX JSON
--- ----
AAA {"PPP": "LLL", "QQQ": "MMM", "RRR": "NNN"}

К вашему сведению, у меня нет доступа к функции row_to_json в базе данных. Попытки включили:

  • конкатенация их в виде строки (довольно сложно сделать, так как нужно "сгруппировать по" XXX, хотя это может ускользнуть от меня, как это сделать)
  • поворот таблицы, ТОГДА пытаясь объединить их в виде строки (чрезвычайно сложно и неэффективно, ~ 100 миллионов строк за время выполнения, к которому я стремлюсь)

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

map_agg в сочетании с GROUP BY - это то, что вы ищете.

Пример

presto:default> SELECT * FROM t;
 id  | key | value
-----+-----+-------
 AAA | QQQ | MMM
 AAA | PPP | LLL
(2 rows)

presto:default> SELECT id, CAST(map_agg(key, value) AS json) FROM t GROUP BY id;
 id  |           _col1
-----+---------------------------
 AAA | {"PPP":"LLL","QQQ":"MMM"}
(1 row)
0 голосов
/ 28 июня 2018

У меня нет prestodb для тестирования, но, возможно, этот ответ поможет вам понять, как это сделать. Я также не знаю, есть ли в наличии рекурсивный CTE. Иногда слово RECURSIVE не поддерживается, но рекурсия работает. Вы должны проверить это самостоятельно. Протестировано на PostgreSQL http://sqlfiddle.com/#!17/07576/4/0.

WITH RECURSIVE CTE AS
(
    SELECT 
        T.XXX, T.YYY, T.ZZZ,  '"' || T.YYY || '": "' || T.ZZZ || '"' AS JSON
    FROM
        T5 T

    UNION ALL

    SELECT
        T.XXX, T.YYY, T.ZZZ, C.JSON || ', ' || '"' || T.YYY || '": "' || T.ZZZ || '"' AS JSON
    FROM
        T5 T
        INNER JOIN CTE C ON C.XXX=T.XXX AND C.YYY || '_' || C.ZZZ>T.YYY || '_' || T.ZZZ
)

SELECT 
    C.XXX,  '{' || MAX(C.JSON) || '}' AS JSON
FROM 
    CTE C
GROUP BY C.XXX
...