0

I've been fighting this for a long time, but I am not able to construct a query, which would select (and preferably also order by) a count of items in an array.

I do have table data like this:

ID    Data
1     {"$id": "1", "InnerArray": [{"$id": "1", "Timestamp": "2020-06-18T09:43:19.4873323+01:00"}, {"$id": "3", "Timestamp": "2020-06-19T08:25:35.7768657+00:00"}]}
etc...

And what did I try...

SELECT JSON_ARRAY_LENGTH("Data" ->'InnerArray'::json) AS lengtha
FROM "mystorage"

also

SELECT JSON_ARRAY_LENGTH("Data"::json ->'InnerArray'::json) AS lengtha

But it sais

SQL Error [22P02]: ERROR: invalid input syntax for type json
  Detail: Token "InnerArray" is invalid.
  Position: 49
  Where: JSON data, line 1: InnerArray

I've tried a lot of different formats but coming from the MS SQL world, my understanding of PostgreSQL seems a bit limited.

2
  • Unrelated to your problem, but: you should really avoid those dreaded quoted identifiers. They are much more trouble than they are worth it. wiki.postgresql.org/wiki/… Commented Oct 14, 2020 at 9:01
  • Yes, I am aware of that, thank you, however I am probably not going to rewrite existing product with hundreds of tables. Commented Feb 28, 2023 at 12:31

2 Answers 2

2

The right hand parameter for the -> operator should be a text value, not a json value. So the cast 'InnerArray'::json is not needed to begin with.

But it's also the reason for your error, because 'InnerArray' isn't a valid JSON value, so you can't cast it to one.

Use:

SELECT json_array_length("Data"::json -> 'InnerArray') AS lengtha

Btw: if you do store JSON values, your column should be defined as jsonb (or at least json), rather than using text (or varchar) and casting it everytime you want to use a JSON function.

Sign up to request clarification or add additional context in comments.

2 Comments

Wow, I thought I tried that one a thousand times.Also, I have my data stored as json datatype, but it's defined by 3rd party product, so not much what I can change anyways. Thanks.
@JiříHerník: if the column is defined as json you can get rid of the cast.
0

You are missing a }. Try this:

select json_array_length('{"$id": "1", "InnerArray": [{"$id": "1", "Timestamp": "2020-06-18T09:43:19.4873323+01:00"}, {"$id": "3", "Timestamp": "2020-06-19T08:25:35.7768657+00:00"}]}'::json->'InnerArray') as lengtha

Best regards,
Bjarni

1 Comment

Thanks, I fixed it, but the point is, that I need to select it from DB field, not inline.

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.