0

I have a table individual customer with a column employmentDetails as json field. The task is to get a customer that has empty locality field

[{
"employmentStatus": "E",
"communicationInfo": {
  "addresses": [
    {
      "id": "1",
      "houseName": "1",
      "locality": null
    }
  ]
}}]

I tried several variants with casting etc with no success, please help me to understand how to query from json object fields. My attempts below that should return some values but returned nothing.

SELECT * FROM crm."IndividualCustomer" AS ic
WHERE (ic."employmentDetails" -> 'employmentStatus')::text = 'E';

SELECT * FROM crm."IndividualCustomer" AS ic
WHERE ic."employmentDetails" -> 'communicationInfo' -> 'adresses[0]' ->> 'locality' = null;

SELECT * FROM crm."IndividualCustomer" AS ic
WHERE ic."employmentDetails" -> 'communicationInfo' -> 'adresses' ->> 'locality' = null; 
1
  • Note that the use of column or table names that require double quotes is discouraged Commented May 5, 2022 at 12:02

1 Answer 1

3

The task is to get a customer that has empty locality field

You can use a JSON path expression:

SELECT * 
FROM crm."IndividualCustomer" AS ic
WHERE ic."employmentDetails" @@ '$[*].communicationInfo.addresses[*].locality == null'

This requires Postgres 12 or later. If you have an older version, you can use the contains operator @>:

WHERE ic."employmentDetails" @> '[{"communicationInfo": {"addresses": [{"locality": null}]}}]'

This assumes that "employmentDetails" is defined as jsonb (which it should be). If it's not, you need to cast it: "employmentDetails"::jsonb.


The condition: (ic."employmentDetails" -> 'employmentStatus')::text = 'E' doesn't work, because -> returns a jsonb (or json) value which can't really be cast to a proper text value (the double quotes are kept if you do so).

You need to use the ->> operator which returns a text value directly: (ic."employmentDetails" ->> 'employmentStatus') = 'E'

However, the top level object is an array, so you would need to pick the e.g. the first array element:

(ic."employmentDetails" -> 0 ->> 'employmentStatus') = 'E'

Note the -> to return the first array element as a proper jsonb value, then the use of ->> on that value.

This can also be done using a JSON path expression to search through all array elements:

WHERE ic."employmentDetails" @@ '$[*].employmentStatus == "E"'`
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.