如何循环 json 数据并计算 postgres 中的值

How to Loop json Data and count the values in postgres

CREATE OR REPLACE FUNCTION file_compare()
RETURNS text LANGUAGE 'plpgsql'
COST 100 VOLATILE AS $BODY$
DECLARE

filedata text[];
fpo_data jsonb;
inddata jsonb;
f_cardholderid text;
f_call_receipt text;
i INT;

BEGIN
  SELECT json_agg((fpdata))::jsonb
  FROM (SELECT fo_data AS fpdata
        FROM fpo
        LIMIT 100
    ) t  INTO fpo_data; 
    i=0;

    FOR inddata IN SELECT * FROM jsonb_array_elements(fpo_data) LOOP

    f_cardholderid := (inddata->>0)::JSONB->'cardholder_id'->>'value';
    f_call_receipt := (inddata->>0)::JSONB->'call_receipt_date'->>'value';

    f_primary_key := f_cardholderid || f_auth_clm_number;

    filedata[i] := jsonb_build_object(
        'fc_primary_key',f_primary_key
    );
    i := i+1;

    END LOOP;   

    RAISE NOTICE 'PRINTING DATA %', filedata;
    END;
$BODY$;

我得到的文件数据如下

 NOTICE:  PRINTING DATA ={"{\"fc_primary_key\": \"A1234567892017/06/27\"}","{\"fc_primary_key\": \"A1234567892017/06/27\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892024/03/01\"}","{\"fc_primary_key\": \"A12345678945353\"}","{\"fc_primary_key\": \"A1234567892023/11/22\"}","{\"fc_primary_key\": \"A12345678945252\"}","{\"fc_primary_key\": \"A1234567892017-07-01\"}"}

现在我想迭代这个文件数据并获取每个 fc_primary_key 值并检查它在整个 json 数据中出现的次数

注意:每个 fc_primary_key 必须仅使用其后出现的值进行验证。它不应该与它之前的 fc_primary 键进行比较。

例如,如果我检查第三个元素 "A1234567892017/08/07",它在它的位置之后出现了 4 次。所以计数必须是 4.

其中第七个元素有相同的"A1234567892017/08/07",但是第七个位置之后没有更多的"A1234567892017/08/07"。所以计数必须为零 "0"

我如何循环数据并获取计数,因为我是 postgres 的新手,我找不到解决方案。请帮忙!!

我用下面的代码得到了你描述的结果。通过取消嵌套数据,您可以利用常规 SQL 语法(偏移、分组、计数),这是您描述的问题的症结所在。

DO
$body$
   DECLARE
      fildata TEXT[] = ARRAY ['{''fc_primary_key'': ''A1234567892017/06/27''}','{''fc_primary_key'': ''A1234567892017/06/27''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892024/03/01''}','{''fc_primary_key'': ''A12345678945353''}','{''fc_primary_key'': ''A1234567892023/11/22''}','{''fc_primary_key'': ''A12345678945252''}','{''fc_primary_key'': ''A1234567892017-07-01''}'];
      count   INTEGER;
   BEGIN
      FOR i IN 1 .. array_length(fildata, 1) LOOP
         SELECT count(*) - 1
           INTO count
           FROM (
                   SELECT unnest(fildata) AS x OFFSET (i - 1)
                ) AS t
          WHERE x = fildata[i]
          GROUP BY x;

         RAISE NOTICE 'Row % appears % times after the current', fildata[i], count;
      END LOOP;
   END
$body$ LANGUAGE plpgsql;

或者,您可以使用开窗而不是偏移量在单个语句中获取整个数据集(如果这有帮助的话)。

SELECT t
     , count(*) OVER (PARTITION BY t ORDER BY rn RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) - 1 AS count
  FROM (
          SELECT row_number() OVER () AS rn, t
            FROM unnest(
                       ARRAY ['{''fc_primary_key'': ''A1234567892017/06/27''}','{''fc_primary_key'': ''A1234567892017/06/27''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892017/08/07''}','{''fc_primary_key'': ''A1234567892024/03/01''}','{''fc_primary_key'': ''A12345678945353''}','{''fc_primary_key'': ''A1234567892023/11/22''}','{''fc_primary_key'': ''A12345678945252''}','{''fc_primary_key'': ''A1234567892017-07-01''}']) AS t
       ) AS x
 ORDER BY rn;