[英]Expand a postgres array of JSON within a single column into multiple records
我有一个称为goals
的表,其中每行包含1个目标。 有关目标特定指标的数据存储在JSON的ARRAY中,名为goal_metrics
。 有时有1个度量,有时有0个度量,其他时候有多个度量。 我想将所有目标指标提取到一个新表中,每个指标有1行,并且该指标所属的原始goal_id。
这是table1
当前的样子:
+---------+------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| goal_id | goal_owner | goal_create_at | goal_metrics |
+---------+------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 69660 | 148191 | 1566576355 | [{'metric_owner': '148191', 'metric_create_at': '1566576374', 'metric_target': '10'}, {'metric_owner': '148191', 'metric_create_at': '1566576403', 'metric_target': '1'}, {'metric_owner': '148191', 'metric_create_at': '1566576428', 'metric_target': '3'}, {'metric_owner': '148191', 'metric_create_at': '1566576450', 'metric_target': '3'}] |
| 68443 | 146270 | 1565911160 | [{'metric_owner': '144534', 'metric_create_at': '1565911175', 'metric_target': '1'}, {'metric_owner': '144352', 'metric_create_at': '1565911191', 'metric_target': '1'}, {'metric_owner': '144352', 'metric_create_at': '1565911212', 'metric_target': '15'}, {'metric_owner': '146270', 'metric_create_at': '1565911353', 'metric_target': '23'}] |
| 68440 | 146270 | 1565910356 | [{'metric_owner': '144061', 'metric_create_at': '1565910380', 'metric_target': '3'}, {'metric_owner': '144061', 'metric_create_at': '1565910462', 'metric_target': '0'}, {'metric_owner': '144534', 'metric_create_at': '1565910523', 'metric_target': '1'}, {'metric_owner': '143866', 'metric_create_at': '1565911422', 'metric_target': '6'}] |
| 68442 | 146270 | 1565910746 | [{'metric_owner': '143866', 'metric_create_at': '1565910863', 'metric_target': '9'}, {'metric_owner': '143866', 'metric_create_at': '1565910881', 'metric_target': '1'}, {'metric_owner': '144534', 'metric_create_at': '1565910905', 'metric_target': '1'}, {'metric_owner': '146270', 'metric_create_at': '1565910927', 'metric_target': '1'}, {'metric_owner': '144534', 'metric_create_at': '1565910956', 'metric_target': '1'}] |
+---------+------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
这就是我想要达到的目标:
+--------------+------------------+---------------+---------+
| metric_owner | metric_create_at | metric_target | goal_id |
+--------------+------------------+---------------+---------+
| 143321 | 1557774894 | 56 | 53513 |
| 143321 | 1557774933 | 100 | 53513 |
| 143321 | 1557774983 | 10 | 53513 |
| 143321 | 1557775102 | 100 | 53513 |
| 143321 | 1557775388 | 100 | 53513 |
| 148191 | 1566576374 | 10 | 69660 |
| 148191 | 1566576403 | 1 | 69660 |
| 148191 | 1566576428 | 3 | 69660 |
| 148191 | 1566576450 | 3 | 69660 |
| 144534 | 1565911175 | 1 | 68443 |
| 144352 | 1565911191 | 1 | 68443 |
| 144352 | 1565911212 | 15 | 68443 |
| 146270 | 1565911353 | 23 | 68443 |
| 144061 | 1565910380 | 3 | 68440 |
| 144061 | 1565910462 | 0 | 68440 |
| 144534 | 1565910523 | 1 | 68440 |
| 143866 | 1565911422 | 6 | 68440 |
| 143866 | 1565910863 | 9 | 68442 |
| 143866 | 1565910881 | 1 | 68442 |
| 144534 | 1565910905 | 1 | 68442 |
| 146270 | 1565910927 | 1 | 68442 |
| 144534 | 1565910956 | 1 | 68442 |
+--------------+------------------+---------------+---------+
如果它只是常规的JSON列,则可以使用SELECT goal_metric -> 'metrics_owner' AS metrics_owner
,但是由于它是可变长度的数组,因此无法使用。 我认为我需要使用JSON_TO_RECORDSET
,并且已经在尝试进行此操作,但是我仍无法实现所需的功能。
有多种可能的方式( Postgres JSON文档 ):
答:使用json_array_elements()
SELECT
goal_id,
(elems ->> 'metric_owner')::int AS metric_owner,
(elems ->> 'metric_create_at')::int AS metric_create_at,
(elems ->> 'metric_target')::int AS metric_target
FROM
table1,
json_array_elements(goal_metrics) as elems
这会将每个数组元素扩展为一行。 可以查询这些扩展的JSON对象的属性。 这给出了text
类型。 如果希望它们为int
类型,则需要强制转换。
B:使用json_to_recordset()
SELECT
goal_id,
elems.*
FROM
table1,
json_to_recordset(goal_metrics)
AS elems(metric_owner int, metric_create_at int,metric_target int)
这一步与(A)中的步骤相同。 您只需要定义输出类型。
C:如果必须定期执行此操作,一次定义输出类型可能很有用。 然后可以在json_populate_recordset()
使用它:
CREATE TYPE metrics_type
AS (metric_owner int, metric_create_at int,metric_target int);
SELECT
goal_id,
elems.*
FROM
table1,
json_populate_recordset(null::metrics_type, goal_metrics) AS elems
first un nest and give a try with ->> option
with basejson as (select goal_id ,goal_owner,unnest(goal_metrics) goal_metrics from jsonmetrics ) select goal_id, goal_owner,goal_metrics->>'metric_owner' "MstricOwner",goal_metrics->>'metric_target' "MetricTGT" from basejson;
goal_id | goal_owner | MstricOwner | MetricTGT
---------+------------+-------------+-----------
4 | 1 | 143866 | 9
2 | 2 | 143866 | 9
2 | 2 | 143867 | 9
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.