簡體   English   中英

將單列中的JSON的postgres數組擴展為多個記錄

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM