3 Ways to Extract a Value from a JSON Document in SQLite

When using SQLite, we can use the following methods to extract data from a JSON document.

The json_extract() Function

As its name suggests, the json_extract() function extracts and returns one or more values from well-formed JSON.

Example:

SELECT json_extract('{
    "dogs" : [
            { "name" : "Wag", "scores" : [ 7, 9 ] },
            { "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
            { "name" : "Woof", "scores" : [ 3, 2, 1 ] }
    ]
}', 
'$.dogs[1]'
);

Result:

{"name":"Bark","scores":[3,4,8,7]}

Arrays are zero based, and so the count starts at 0. Therefore, we specified [1] to get the second element within the dogs array, which happens to be a JSON object.

We can return just the name of the dog at that position in the array by adding to our path:

SELECT json_extract('{
    "dogs" : [
            { "name" : "Wag", "scores" : [ 7, 9 ] },
            { "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
            { "name" : "Woof", "scores" : [ 3, 2, 1 ] }
    ]
}', 
'$.dogs[1].name'
);

Result:

Bark

We can use json_extract() to return multiple paths:

SELECT json_extract('{
    "dogs" : [
            { "name" : "Wag", "scores" : [ 7, 9 ] },
            { "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
            { "name" : "Woof", "scores" : [ 3, 2, 1 ] }
    ]
}', 
'$.dogs[0].name',
'$.dogs[1].name',
'$.dogs[2].name'
);

Result:

["Wag","Bark","Woof"]

When we extract values from multiple paths, the values are returned in an array.

The -> Operator

The -> operator extracts a subcomponent from a JSON document and returns a JSON representation of that subcomponent.

Therefore, we can change the first example to this:

SELECT '{
    "dogs" : [
            { "name" : "Wag", "scores" : [ 7, 9 ] },
            { "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
            { "name" : "Woof", "scores" : [ 3, 2, 1 ] }
    ]
}' -> '$.dogs[1]';

Result:

{"name":"Bark","scores":[3,4,8,7]}

The -> operator is subtly different to the json_extract() function:

  • The -> operator always returns a JSON representation of the subcomponent.
  • The json_extract() function only returns JSON if there are two or more path arguments (because the result is then a JSON array) or if the single path argument references an array or object.
  • If there’s only one path argument and that path references a JSON null or a string or a numeric value, then json_extract() returns the corresponding SQL NULL, TEXT, INTEGER, or REAL value.

Therefore, here’s what happens when we extract a dog’s name from our JSON:

SELECT '{
    "dogs" : [
            { "name" : "Wag", "scores" : [ 7, 9 ] },
            { "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
            { "name" : "Woof", "scores" : [ 3, 2, 1 ] }
    ]
}' -> '$.dogs[1].name';

Result:

"Bark"

This time it’s surrounded by quotes. That’s because it returned a JSON representation of the value. When we extracted the same value with json_extract() previously, we got an SQL representation of the value.

However, we can also use the ->> operator to return an SQL representation.

The ->> Operator

The ->> operator works the same way as the -> operator, except that ->> returns an SQL representation of the specified subcomponent. Specifically, it returns an SQL TEXT, INTEGER, REAL, or NULL value that represents the selected subcomponent, or NULL if the subcomponent does not exist.

Therefore, here’s what happens when we use the ->> operator to extract the dog’s name:

SELECT '{
    "dogs" : [
            { "name" : "Wag", "scores" : [ 7, 9 ] },
            { "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
            { "name" : "Woof", "scores" : [ 3, 2, 1 ] }
    ]
}' ->> '$.dogs[1].name';

Result:

Bark

It’s no longer enclosed in quotes.