Here is a small example to prove my point: CREATE TABLE some_data ( data hstore ); INSERT INTO some_data VALUES ('a=>bla'), ('access=>bla'), ('access=>user'); Now taking your JSON as an example, we can do something like this: WITH condition_elements AS ( SELECT key, ARRAY(SELECT jsonb_array_elements_text(value->'authorized_keys')) AS value FROM jsonb_each(' { "matricule": {"authorized_keys":["12"], "unauthorized_keys": ["1", "2", "20"]}, "departement": {"authorized_keys": ["it"], "unauthorized_keys":["finance", "account"]}, "access": {"authorized_keys" : ["superuser", "user", "login"], "unauthorized_keys" : ["web"]} }'::jsonb) ) SELECT data->key AS key, value, data->key=ANY(value) AS matches FROM some_data, condition_elements; The actual output is to describe what to expect from above: key │ value │ matches ──────┼────────────────────────┼───────── │ {superuser,user,login} │ bla │ {superuser,user,login} │ f user │ {superuser,user,login} │ t │ {12} │ │ {12} │ │ {12} │ │ {it} │ │ {it} │ │ {it} │ If we move the necessary part to a condition, it will work nicely: WITH condition_elements (... like above ...) SELECT data, key, value FROM some_data, condition_elements WHERE data->key=ANY(value); data │ key │ value ──────────────────┼────────┼──────────────────────── "access"=>"user" │ access │ {superuser,user,login}