Плоско-многоуровневые вложенные данные - PullRequest
0 голосов
/ 08 июня 2018

В BQ я использовал ARRAY_AGG(STRUCT(... для реструктуризации некоторых плоских данных, но хотел пойти еще дальше: создать еще один массив записей в массиве записей.Хотя STRUCT не существует в PostgreSQL, мне интересно, как можно решить эту проблему и там.

Учитывая плоские данные:

WITH a AS (
SELECT 'ABC' company, 'adress1' address, 'name1' name, 'email1' email, 'work' ph_type, '+123' ph_nr
UNION ALL
SELECT 'ABC' company, 'adress1' address, 'name1' name, 'email1' email, 'cell' ph_type, '+987'
 UNION ALL
SELECT 'DEF' company, 'adress2' address, 'name2' name, 'email2' email, 'work' ph_type, '+127'
 UNION ALL
SELECT 'DEF' company, 'adress2' address, 'name2' name, 'email2' email, 'cell' ph_type, '+988'
 UNION ALL
SELECT 'XYZ' company, 'adress3' address, 'name3' name, 'email3' email, 'work' ph_type, '+456'
)

Я могу вкладывать contact, например,

SELECT company, address, ARRAY_AGG(STRUCT(name, email, ph_type, ph_nr)) contact
FROM a
GROUP BY company, address
ORDER BY 1

но как я могу вложить, в том же операторе выбора , phones (массив записей в contact)?

Представление JSON будет выглядетьнапример - для первого контакта:

[
 {
  "company": "ABC",
  "address": "adress1",
  "contact": [
    {
      "name": "name1",        
      "email": "email1",
      "phone": [
        {
         "ph_type": "work",
         "ph_nr": "+123"
        },
        {
         "ph_type": "cell",
         "ph_nr": "+987"
        }
    },
   ...

Возможно, это можно сделать с помощью предложения или подвыбора WITH для последовательной обработки агрегатов, но не уверен, что это будет работать хорошо (данные читаются дважды?).

У меня есть 600 миллионов записей для ежедневного анализа, поэтому я задаюсь вопросом о наиболее эффективном способе.

РЕДАКТИРОВАТЬ : исправлено определение имени

1 Ответ

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

Ответ на ваш вопрос - два уровня агрегирования.

Однако сам вопрос меня смущает, поскольку в запросе используется name, но это не определено в данных.

Вот пример того, что нужно сделать:

SELECT company, address, ARRAY_AGG(STRUCT(email, phones)) as contact
FROM (SELECT company, name, address, email, ARRAY_AGG(STRUCT(ph_type, ph_nr)) as phones
      FROM a
      GROUP BY company, name, address, email
     ) a
GROUP BY company, address
ORDER BY 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...