2017-09-14 94 views
0

我的表有很多行,每行都包含一個jsonb對象。如何遍歷PostgreSQL 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是更充分的證明方法。

但是,我無法弄清楚如何基本迭代每行中的每個「Record ID」,並將同一個表中每行中的「Record ID」與每個其他「Record 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; 

...因爲查詢只檢查在「標識符」數組的索引0的「的recordId」值。

我該如何執行類似 SELECT [email protected]>'RecordID' 爲了讓我的查詢檢查'標識符'數組中的'RecordID'值的每個索引?

任何和所有的幫助,非常感謝!謝謝!

  • 我希望只用Postgres查詢來完成此任務,而不是通過使用外部語言訪問此數據。 (Python等)

回答

0

我解決了這個問題,主要是在我的嵌套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; 
相關問題