Sql 平面到多级嵌套数据

Sql 平面到多级嵌套数据,sql,postgresql,Sql,Postgresql,在BQ中,我使用了ARRAY\u AGG(STRUCT(…)来重新构造一些平面数据,但我想更进一步:在记录数组中创建另一个记录数组。 虽然PostgreSQL中不存在STRUCT,但我也对如何在那里解决这个问题感兴趣 考虑到平面数据: WITH a AS ( SELECT 'ABC' company, 'adress1' address, 'name1' name, 'email1' email, 'work' ph_type, '+123' ph_nr UNION ALL SELECT 'AB

在BQ中,我使用了
ARRAY\u AGG(STRUCT(…
)来重新构造一些平面数据,但我想更进一步:在记录数组中创建另一个记录数组。 虽然PostgreSQL中不存在STRUCT,但我也对如何在那里解决这个问题感兴趣

考虑到平面数据:

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'
)
我可以这样嵌套
联系人

SELECT company, address, ARRAY_AGG(STRUCT(name, email, ph_type, ph_nr)) contact
FROM a
GROUP BY company, address
ORDER BY 1
但是我如何才能在同一个select语句中嵌套
电话
(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
子句或subselect来完成,以按顺序处理聚合,但不确定这是否会执行良好(数据读取两次?)

我每天要解析6亿条记录,所以我想知道最有效的方法


编辑:更正名称定义

您的问题的答案是两级聚合

然而,这个问题本身让我感到困惑,因为查询使用了
名称
,但数据中没有定义

下面是一个操作示例:

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

您的问题的答案是两个级别的聚合

然而,这个问题本身让我感到困惑,因为查询使用了
名称
,但数据中没有定义

下面是一个操作示例:

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

我的缺点-你是对的,我已经更正了查询。我想知道子查询是否是唯一的方法。问题是大型数据集的性能。性能指标:我使用了一个部分数据集,我有-49M条记录(5GB)-在两个数组_AGG上都有ORDER BY时,需要294个处理,而在没有ORDER BY的情况下需要104个处理。在all上进行排序更方便,因此将跳过。但仍然希望减少查询时间。@YannickEinsweiler…在一个大表上进行两级聚合将非常昂贵。我的错-你是对的,我已经更正了查询。我很好奇g如果子查询是唯一的方法。关注的是大型数据集的性能。性能指标:我使用了一个部分数据集,我有-49M条记录(5GB)-当在两个数组_AGG上都有ORDER BY时,需要294个处理,而在没有ORDER BY的情况下需要104个处理。在all上进行排序更方便,因此将跳过。但仍希望减少查询时间。@YannickEinsweiler…在一个大表上进行两级聚合将非常昂贵。