Assume I have a table product
:
create table product
(
attributes jsonb
);
with data:
insert into product (attributes)
values ('{"Color": "Red"}'),
('{"color": "White"}'),
('{"COLOR": "Blue"}');
How do I select all records' color
attribute in PostgreSQL 9.4+? Since the keys differ in casing, I am unable to use this syntax:
select
attributes->>'color' as color
from product;
My expected output would be:
Red
White
Blue
I also tried using this syntax (works but feels hacky):
select
coalesce(
attributes->>'color',
attributes->>'Color',
attributes->>'COLOR') as color
from product;
Is this possible? I can see that it might conflict should you have color
and Color
keys on the same object, so I would not be surprised if this is not a thing.
References:
PostgreSQL has two native operators -> and ->> to query JSON documents. The first operator -> returns a JSON object, while the operator ->> returns text. These operators work on both JSON as well as JSONB columns. There are additional operators available for JSONB columns.
JSONB and IndexesPostgreSQL can use indexes for the text results as compare operands. GIN index can be used by the GIN JSONB operator class.
The jsonb datatype is an advanced binary storage format with full processing, indexing and searching capabilities, and as such pre-processes the JSON data to an internal format, which does include a single value per key; and also isn't sensible to extra whitespace or indentation.
If duplicate keys are specified in the input, only the last value is kept. In general, most applications should prefer to store JSON data as jsonb , unless there are quite specialized needs, such as legacy assumptions about ordering of object keys. RFC 7159 specifies that JSON strings should be encoded in UTF8.
You should extract the pairs (key, value)
to use the function lower()
select value as color
from product, jsonb_each(attributes)
where lower(key) = 'color';
or using a more verbose syntax:
select value as color
from product
cross join jsonb_each(attributes)
where lower(key) = 'color';
This cross join
is a lateral join, the function jsonb_each()
is executed once for each row from product.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With