3

We have a jsonb column with data of the type:

"basket": {
    "total": 6,
    "items": [
        {    "type": "A",    "name": "A",    "price": 1    },
        {    "type": "A",    "name": "B",    "price": 2    },
        {    "type": "C",    "name": "C",    "price": 3    },
    ] 
}

We need to construct few queries that will filter specific elements of the items[] array for SELECT and SUM.

We have PG v9.6 so using jsonb_path_query_array didn't work.

Using basket->'items' @> '{"type":"A"}' works to find all entries that has type-A.

But how do we get subquery to

  • select only basket items of type-A
  • sum of prices of items of type-A

Thank you!

1 Answer 1

3

This will select the required items:

select * from jsonb_array_elements('{"basket": 
{
    "total": 6,
    "items": [
        {    "type": "A",    "name": "A",    "price": 1    },
        {    "type": "A",    "name": "B",    "price": 2    },
        {    "type": "C",    "name": "C",    "price": 3    }
    ] 
}}'::jsonb#>'{basket,items}') e(it)
where it->>'type' = 'A';

and this the sum of prices:

select sum(cast(it->>'price' as numeric)) from  jsonb_array_elements('{"basket": 
{
    "total": 6,
    "items": [
        {    "type": "A",    "name": "A",    "price": 1    },
        {    "type": "A",    "name": "B",    "price": 2    },
        {    "type": "C",    "name": "C",    "price": 3    }
    ] 
}}'::jsonb#>'{basket,items}') e(it)
where it->>'type' = 'A';
Sign up to request clarification or add additional context in comments.

5 Comments

What is the name of the e() function? does it create a temp var?
e() is not a function. "e" is the name of the subquery. In this case I opt to name the returning column in the query as "it". These are just aliases for the values already returned but you always need to name the subqueries in order to be able to refer to it.
Yes, I understand having to name it to be able to refer to it, I've never seen this syntax though. What's the difference between e(it) or AS it ? both seem to work the same way..
Hi. You are right. It doesn't matter in this case as the subquery only returns single column of type jsonb object - actually in a column named "value". The value is also accessible as it.value (if written only as it and not e(it)). Just habits kicking in. This is a very useful syntax when the subquery returns many columns. It is like this, e is an alias for the subquery (it could be a table) and it is an alias for the column in the query/table. If many columns it would be e(col1, col2, col3) for example. See here: postgresql.org/docs/11/queries-table-expressions.html
aaaaaah yes (lightbulb moment) That all makes sense now. Thanks for clarifying the syntax.

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.