Postgresql jsonb выбирает различные элементы массива (с одинаковыми ключами) в строке - PullRequest
0 голосов
/ 29 октября 2018

Использование этого jsonb:

[
    {
        "#text": "ANNALS OF THE RHEUMATIC DISEASES",
        "@type": "source"
    },
    {
        "#text": "ANN RHEUM DIS",
        "@type": "source_abbrev"
    },
    {
        "#text": "Ann. Rheum. Dis.",
        "@type": "abbrev_iso"
    },
    {
        "#text": "ANN RHEUM D",
        "@type": "abbrev_11"
    },
    {
        "#text": "ANN RHEUM DIS",
        "@type": "abbrev_29"
    },
    {
        "#text": "Comparison of initial versus delayed introduction of a treat-to-target strategy in patients with recent-onset rheumatoid arthritis: results of the T-4 3-year study",
        "@type": "item"
    }
]

Я могу сделать выбор следующим образом:

select b.x->>'#text' from b 
where b.x @> '{"@type" : "source"}'::jsonb

но я хочу выбрать, например, #text, где ключом является "item", "abbrev_iso" и "source" в одной строке. Можно ли это сделать простым SQL или лучше написать функцию, которая поможет с запросом?

Результат должен выглядеть примерно так:

Source                                 Abbrev                Item
ANNALS OF THE RHEUMATIC DISEASES       Ann. Rheum. Dis.      Comparison of initial versus....

1 Ответ

0 голосов
/ 30 октября 2018

Следующий код работает. Первоначальные тесты показали, что на 10000 записях это примерно в 8 раз медленнее, чем получение того же результата при объединении трех традиционных таблиц.

with a as
  (select id,
          xml_json#>'{titles,title}' y
   from source),
     items as
  ( select id,
           e.item ->> '#text' as text_val,
                      e.item ->> '@type' as type
   from a,
        jsonb_array_elements(a.y) as e(item))
select b.id,
       j.text_val source,
                  i.text_val item,
                  ab.text_val abbrev
from items b
left join items j on j.id = b.id
and j.type = 'source'
left join items i on i.id = b.id
and i.type = 'item'
left join items ab on ab.id = b.id
and ab.type = 'abbrev_iso'
...