[英]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.