The docs on json_each on sqlite.com are brief.
The following may help to better understand how to use json_each and other json functions.
Create a table JsonTest
. The column Reply
contains json values.
CREATE TABLE "JsonTest" (
"Id" INTEGER NOT NULL UNIQUE,
"Reply" TEXT,
PRIMARY KEY("Id" AUTOINCREMENT)
)
Insert some records into the table
INSERT INTO JsonTest (Reply)
SELECT
'{"id": 2, "status": "ok", "body": [{"Ftr": "Gears", "Val": "10"},{"Ftr": "Brake", "Val": "Disc-Brake"}]}' as REPLY
UNION SELECT '{"id": 4, "status": "ok", "body": [{"Ftr": "Gears", "Val": "12"},{"Feature": "Brake", "Val": "Disc-Brake"}]}'
UNION SELECT 'Error'
UNION SELECT '{"id": 1, "status": "nok", "body": "empty"}'
UNION SELECT 'Error'
UNION SELECT '{"id": 5, "status": "nok", "body": "empty"}'
UNION SELECT '{"id": 6, "status": "ok", "body": [{"Ftr": "Gears", "Val": "21"},{"Ftr": "Brake", "Val": "V-Brake"}]}'
UNION SELECT '{"id": 8, "status": "ok", "body": [{"Ftr": "Gears", "Val": "18"},{"Ftr": "Brake", "Val": "V-Brake"}]}';
As you can see the
- some rows only contain
Error
and are not valid json
- other rows have a valid json object the property
body
has either a value empty
or a value of type array like this
[
{"Ftr": "Gears", "Val": "21"},
{"Ftr": "Brake","Val": "V-Brake"}
]
If the column Reply
would always have a valid json value like this '{"id": 5, "status": "nok" ...}
we could query for json field status like this:
SELECT JsonTest.id, jsonEach.Value
FROM JsonTest,json_each(JsonTest.Reply, '$.status') as jsonEach
WHERE JsonTest.Reply not like 'Error';
But since some rows / records are not valid json a subquery like this (SELECT *, ...) as sq
combined with json_each(Reply, ...)
can be used to filter all records with valid json WHERE JSON_VALID(Reply)
.
SELECT subquery.RecordId, subquery.Reply_id, jsonEach.value
FROM
(
SELECT *, Id as RecordId, json_extract(Reply, '$.id') as Reply_id
FROM JsonTest
WHERE JSON_VALID(Reply) -- filter to get only valid json rows
AND json_extract(Reply, '$.status') like "ok"
AND json_extract(Reply, '$.body[1].Val') like "V-Brake"
) as subquery, json_each(Reply, '$.body') as jsonEach;
In sqlite-browser this returns this result