Home > database >  Get nested objects values from JSON in Postgres
Get nested objects values from JSON in Postgres

Time:11-03

So here is my JSON column in my Postgres DB:

{
  "objekt_art": {
    "86": {
      "code": "86",
      "bezeichnung_de": "Kino",
      "bezeichnung_fr": "Cinéma",       
      "bezeichnung_it": "Cinema",
      "bezeichnung_en": null,
      "kurz_bezeichnung_de": "Kino",
      "relevant_fuer_berechnung_steuerquote": true
    },
    "27": {
      "code": "27",
      "bezeichnung_de": "Kiosk",
      "bezeichnung_fr": "Kiosque",
      "bezeichnung_it": "Chiosco",
      "bezeichnung_en": null,
      "kurz_bezeichnung_de": "Kiosk",
      "relevant_fuer_berechnung_steuerquote": true
    }
  }
}

I need to be able to query the bezechnung_de for example where code = 86. The number of code i can pass from another table.

How can i for example make a query with two columns. One with the number and the second with bezeichnung_de.

Like this:

Code Bez
86   Kino

CodePudding user response:

Sample data structure and sample table for join data: dbfiddle

select
  je.value -> 'code' as "Code",
  je.value -> 'bezeichnung_de' as "Bez"
from
  test t
  cross join jsonb_each((data::jsonb ->> 'objekt_art')::jsonb) je
  -- In table test_join I insert value 86 for join record
  inner join test_join tj on je.key::int = tj.json_id

CodePudding user response:

As you know the code, this is fairly easy:

select t.the_column -> 'objekt_art' -> '86' ->> 'code' as code,
       t.the_column -> 'objekt_art' -> '86' ->> 'bezeichnung_de' as bez
from the_table t
where ...

The value '86' can be a parameter. The first expression to select the code isn't really needed though, as you could replace it with the constant value (=parameter) directly.

If the "outer" JSON key isn't the same value as the code value, you could use something like this:

select o.value ->> 'code' as code, 
       o.value ->> 'bezeichnung_de' as bez
from the_table t
  cross join jsonb_each(t.the_column -> 'objekt_art') o(key, value)
where o.key = '86'
  and ... other conditions ...

If you are using Postgres 13 or later, this can also be written as a JSON path expression:

select a.item ->> 'code' as code,
       a.item ->> 'bezeichnung_de' as bez
from (
  select jsonb_path_query_first(t.the_column, '$.objekt_art.* ? (@.code == "86")') as item
  from the_table t
  where ....
) a

All examples assume that the column is defined with the data jsonb which it should be. If it's not you need to cast it: the_column::jsonb

  • Related