首页 > 解决方案 > 从多列创建 jsonb

问题描述

我在通过 Postgres 10 创建 jsonb 时遇到问题。我需要提取列中的值并构造一个 json 格式的输出。我设法提取了该值,但在将其构造为 JSON 格式时遇到了问题

P|61||||^^||^^|U||||||||||||||||||||||||||<CR>
O|61|15^1^15|KK4002259|GLU^Glucose (GOD-POD Method)^^
R|170|AST^Aspartate Aminotransferase^^F|22.657989^^^^
R|171|ALP^Alkaline phosphatase^^F|107.636995^^^^
R|172|TP^Total Protein^^F|85.245151^^^^
R|173|TG^Triglycerides^^F|1.348633^^^^
R|174|HDL^HDL-Cholesterol^^F|1.238458^^^^
R|175|CHOL^Total Cholesterol^^F|5.073630^^^^
R|176|UA^Uric Acid^^F|309.705876^^^^
R|177|BUN^Urea^^F|4.412234^^^^

以上是我的输入文件,它发生在多行中

目前我的代码如下。

CREATE OR REPLACE FUNCTION azintin(p_filenm character varying, p_instcd character varying, p_brhcd character varying, p_deptcd character varying, p_trxcd character varying, p_msg text)
 RETURNS jsonb
 LANGUAGE plpgsql
AS $function$
DECLARE
    v_respcd    text;   
    v_respmsg   aft_intarcbox.respond_message%type; 
    v_cnt       INT = 0;
    v_msgar     text[];
    v_msgln     text;
    v_crln      char(2) := chr(13)||chr(10);
    v_msgtyp    character varying(3);
    v_flag      character varying;
    v_result    json;
    macres      azt_macres%rowtype;


BEGIN   

    v_msgar := string_to_array(p_msg, '<STX>');
    
    IF p_trxcd = 'AZ0001' then
    
        -- Loop thru the message array
        FOREACH v_msgln IN ARRAY v_msgar 
        LOOP
                
            IF v_msgtyp='R' THEN
          
                v_flag := split_part(v_msgln,'|',2);

                macres.analyzer_test_full_desc := UPPER((string_to_array(split_part(v_msgln,'|',3),'^'))[2]);
                macres.data_reading := (string_to_array(split_part(v_msgln,'|',4),'^'))[1];

              SELECT jsonb_build_object(macres.analyzer_test_full_desc,macres.data_reading)
                       into v_result from azt_macres;

目前我的v_result输出是这样的

{"AST": 22.657989}

我想创建一个像这样的json

{"AST": 22.657989, "ALP": 107.636995, "TP":85.245151, "TG":1.348633}

标签: jsonpostgresqlstored-proceduresjsonb

解决方案


如果输入是每行包含一项的数组,则可以使用 SQL 聚合来实现此目的。无需使用 FOR 循环。

select jsonb_object_agg(split_part(items[3], '^', 1), split_part(items[3], '^', 2))
from (
  select string_to_array(element, '|') as items
  from unnest(v_msgar) as t(element)
) t   
where items[1] = 'R'

在函数内部,它会是这样的:

  ...

  v_msgar := ....; -- put the items into the array

  select jsonb_object_agg(split_part(items[3], '^', 1), split_part(items[3], '^', 2))
     into v_result  
  from (
    select string_to_array(element, '|') as items
    from unnest(v_msgar) as t(element)
  ) t   
  where items[1] = 'R';

  ...

在线示例


推荐阅读