sql >> Databasteknik >  >> RDS >> PostgreSQL

Fråga postgres jsonb efter värde oavsett nycklar

För enkla JSONs kan du använda mer lämplig fråga som

select * 
from mytable t 
where exists (
  select 1 
  from jsonb_each_text(t.jsonbfield) j 
  where j.value = 'hello');

Det fungerar bra för JSONs som i ditt exempel men hjälper inte för mer komplexa JSONs som {"a":"hello","b":1,"c":{"c":"world"}}

Jag kan föreslå att skapa den lagrade funktionen som

create or replace function jsonb_enum_values(in jsonb) returns setof varchar as $$
begin
  case jsonb_typeof($1)
    when 'object' then
      return query select jsonb_enum_values(j.value) from jsonb_each($1) j;
    when 'array' then
      return query select jsonb_enum_values(a) from jsonb_array_elements($1) as a;
    else
      return next $1::varchar;
  end case;
end
$$ language plpgsql immutable;

för att lista alla värden inklusive rekursiva objekt (det är upp till dig vad du ska göra med arrayer).

Här är användningsexempel:

with t(x) as (
  values
    ('{"a":"hello","b":"world","c":1,"d":{"e":"win","f":"amp"}}'::jsonb),
    ('{"a":"foo","b":"world","c":2}'),
    ('{"a":[{"b":"win"},{"c":"amp"},"hello"]}'),
    ('[{"a":"win"}]'),
    ('["win","amp"]'))
select * 
from t 
where exists (
  select *
  from jsonb_enum_values(t.x) j(x) 
  where j.x = '"win"');

Observera att dubbla citattecken runt strängvärdet.




  1. .sql-filen returnerar inte kolumnrubriken i csv-filen

  2. Laravel 5.3:Syntaxfel eller åtkomstöverträdelse:1463 Icke-grupperande fält 'distans' används i HAVING-satsen

  3. PGError:ERROR:aggregeringar är inte tillåtna i WHERE-satsen på en AR-fråga för ett objekt och dess has_many-objekt

  4. SELECT * FROM tbl WHERE clm LIKE CONCAT('%',<other sql-query LIMIT 1>,'%') - HUR?