在 Postgres SQL 中使用 group by 构造 JSON 对象

Structure the JSON object using group by in Postgres SQL

我正在尝试使用 Postgres SQL 查询创建结构。该结构被定义为更快地搜索应用程序的一些高级功能,所以这就是我无法更改此结构的原因,我想这是目前最可行的结构。

Table: provider_schedule

|_id|user_id|day|start_time|end_time|hours_format|
|---|-------|---|----------|--------|------------|
|13 |87     |0  |09:00:00  |12:00:00|1           |
|14 |87     |0  |15:00:00  |20:00:00|1           |
|15 |87     |1  |09:00:00  |12:00:00|1           |
|16 |87     |1  |15:00:00  |20:00:00|1           |
|17 |87     |2  |15:00:00  |20:00:00|1           |
|18 |87     |2  |09:00:00  |12:00:00|1           |

查询:

SELECT day, jsonb_object_agg(start_time, end_time) as time_array, min(hours_format) as hours_format 
FROM provider_schedule 
WHERE user_id = 87 
GROUP BY day;

当前结果:

[{
    day: 0,
    time_array: {
      '09:00:00': '12:00:00',
      '15:00:00': '20:00:00'
    },
    hours_format: 1
  },
  {
    day: 1,
    time_array: {
      '09:00:00': '12:00:00',
      '15:00:00': '20:00:00'
    },
    hours_format: 1
  },
  {
    day: 2,
    time_array: {
      '09:00:00': '12:00:00',
      '15:00:00': '20:00:00'
    },
    hours_format: 1
  }
]

预期结果:

[{
    day: 0,
    time_array: [{
        start_time: '09:00:00',
        end_time: '12:00:00'
      },
      {
        start_time: '15:00:00',
        end_time: '20:00:00'
      }
    ],
    hours_format: 1
  },
  {
    day: 1,
    time_array: [{
        {
          start_time: '09:00:00',
          end_time: '12:00:00'
        },
        {
          start_time: '15:00:00',
          end_time: '20:00:00'
        }]
      hours_format: 1
    },
    {
      day: 2,
      {
        start_time: '09:00:00',
        end_time: '12:00:00'
      },
      {
        start_time: '15:00:00',
        end_time: '20:00:00'
      }],
    hours_format: 1
  }
]

我想要查询中的预期结构。我不想在查询结果后使用 JavaScript 创建此结构。提前谢谢你。

您需要聚合级别,因为您不能直接嵌套聚合函数 - 这就是您需要获取整个结果的数组和一天的行作为数组的条件。

select jsonb_agg(single_day)
from (
  select jsonb_build_object('day', day, 
                            'hours_format', min(hours_format), 
                            'time_array', jsonb_agg(jsonb_build_object('start_time', start_time, 'end_time', end_time) order by start_time)) as single_day
  from provider_schedule
  where user_id = 87
  group by day
) t  

Online example