【问题标题】:How to iterate through PostgreSQL jsonb array values for purposes of matching within a query如何遍历 PostgreSQL jsonb 数组值以在查询中进行匹配
【发布时间】:2017-09-14 17:55:44
【问题描述】:

我的表有很多行,每行包含一个 jsonb 对象。

此对象包含一个数组,其中可能有多个同名但具有不同值的键。

我的目标是扫描我的整个表并验证在这个 json 对象的数组中哪些行包含重复值。

第 1 行示例数据:

{
    "Name": "Bobb Smith",
    "Identifiers": [
        {
            "Content": "123",
            "RecordID": "123",
            "SystemID": "Test",
            "LastUpdated": "2017-09-12T02:23:30.817Z"
        },
        {
            "Content": "abc",
            "RecordID": "abc",
            "SystemID": "Test",
            "LastUpdated": "2017-09-13T10:10:21.598Z"
        },
        {
            "Content": "def",
            "RecordID": "def",
            "SystemID": "Test",
            "LastUpdated": "2017-09-13T10:10:21.598Z"
        }
    ]
}

第 2 行示例数据:

{
    "Name": "Bob Smith",
    "Identifiers": [
        {
            "Content": "abc",
            "RecordID": "abc",
            "SystemID": "Test",
            "LastUpdated": "2017-09-13T10:10:26.020Z"
        }
    ]
}

我当前的查询最初用于根据名称值查找重复项,但是,在名称可能被混淆的情况下,使用记录 ID 是一种更完整的证明方法。

但是,我无法弄清楚如何从本质上对每一行中的每个“记录 ID”进行迭代,并将该“记录 ID”与同一表中每一行中的每个其他“记录 ID”进行比较以查找匹配项。

我当前的查询匹配“姓名”:

discard temporary;

with dupe as (
    select 
    json_document->>'Name' as name, 
    json_document->'Identifiers'->0->'RecordID' as record_id, 
    from staging
)


 select name as "Name", record_id::text as "Record ID"
 from dupe da
 where ( select count(*) from dupe db where db.name = da.name) > 1
 order by full_name;

如果两行中的“姓名”字段包含相同的“鲍勃”拼写,上述查询将返回匹配的行。

我需要使用“RecordID”字段的嵌套值来实现相同的功能。

这里的问题是 json_document->'Identifiers'->0->'RecordID' 仅返回数组内索引 0 处的“RecordID”。

例如,这不起作用:

discard temporary;
with dupe as (
    select 
    json_document->>'Name' as name, 
    json_document->'Identifiers'->0->'RecordID' as record_id, 
    from staging
)

select name as "Name", record_id::text as "Record ID"
from dupe da
where ( select count(*) from dupe db where db.record_id = da.record_id) > 1
order by full_name;

...因为查询只检查 'Identifiers' 数组的索引 0 处的 'RecordID' 值。

我怎么能从本质上执行类似的操作 SELECT json_document@>'RecordID' 为了让我的查询检查 'Identifiers' 数组中的每个索引是否有 'RecordID' 值?

非常感谢任何和所有帮助!谢谢!

  • 我希望仅通过 Postgres 查询而不是通过使用外部语言访问此数据来完成此操作。 (Python 等)

【问题讨论】:

    标签: json postgresql


    【解决方案1】:

    我通过在嵌套的 jsonb 数组上执行类似“unnest()”的jsonb_array_elements() 解决了这个问题。

    通过在子查询中执行此操作,然后使用原始查询的变体扫描这些结果,我能够获得所需的结果。

    这是我想出的。

    with dupe as (
    select
    json_document->>'Name' as name,
    identifiers->'RecordID' as record_id
    from (
      select *,  
      jsonb_array_elements(json_document->'Identifiers') as identifiers
      from staging
    ) sub
    group by record_id, json_document
    order by name
    ) 
    
    select * from dupe da where (select count(*) from dupe db where 
    db.record_id = da.record_id) > 1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-17
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多