SQLite
 sql >> Base de Dados >  >> RDS >> SQLite

SQLite JSON_EACH()

No SQLite, json_each() é uma função com valor de tabela que percorre o valor JSON fornecido como seu primeiro argumento e retorna uma tabela que consiste em uma linha para cada elemento da matriz ou membro do objeto.

Fornecemos o valor JSON como um argumento quando chamamos a função.

Opcionalmente, podemos passar um segundo argumento, que especifica um caminho para começar. Quando fazemos isso, json_each() trata esse caminho como o elemento de nível superior.

O json_each() A função apenas percorre os filhos imediatos do array ou objeto de nível superior, ou apenas o próprio elemento de nível superior se o elemento de nível superior for um valor primitivo. Para percorrer recursivamente a subestrutura JSON, use json_tree() em vez de.

Sintaxe

Podemos usar a função das seguintes maneiras:

json_each(X)
json_each(X,P)

Onde X representa o JSON e P é um argumento opcional que representa o caminho a ser tratado como o nível superior.

Exemplo

Aqui está um exemplo para demonstrar como funciona:

SELECT * FROM json_each('{ "name" : "Woof", "age" : 10 }');

Resultado:

+------+-------+---------+------+----+--------+---------+------+
| key  | value |  type   | atom | id | parent | fullkey | path |
+------+-------+---------+------+----+--------+---------+------+
| name | Woof  | text    | Woof | 2  | null   | $.name  | $    |
| age  | 10    | integer | 10   | 4  | null   | $.age   | $    |
+------+-------+---------+------+----+--------+---------+------+

Podemos ver que cada membro do objeto possui sua própria linha com algumas informações úteis, como seu tipo (valor do texto SQL), caminho, etc.

Em relação ao id coluna, de acordo com a documentação do SQLite, este é um número interno de manutenção, cujo cálculo pode mudar em versões futuras. A única garantia é que o id coluna será diferente para cada linha.

A coluna pai é sempre null ao chamar json_each() . Esta coluna se torna mais significativa ao usar json_tree() .

Matriz

Neste exemplo, o valor JSON é uma matriz:

SELECT * FROM json_each('[ 10, 30, 45 ]');

Resultado:

+-----+-------+---------+------+----+--------+---------+------+
| key | value |  type   | atom | id | parent | fullkey | path |
+-----+-------+---------+------+----+--------+---------+------+
| 0   | 10    | integer | 10   | 1  | null   | $[0]    | $    |
| 1   | 30    | integer | 30   | 2  | null   | $[1]    | $    |
| 2   | 45    | integer | 45   | 3  | null   | $[2]    | $    |
+-----+-------+---------+------+----+--------+---------+------+

Especifique um caminho


Podemos usar um segundo argumento para especificar um caminho para tratar como o nível superior.

Exemplo:
SELECT * FROM json_each('{ "a" : 1, "b" : [ 4, 7, 8 ] }', '$.b');

Resultado:

+-----+-------+---------+------+----+--------+---------+------+
| key | value |  type   | atom | id | parent | fullkey | path |
+-----+-------+---------+------+----+--------+---------+------+
| 0   | 4     | integer | 4    | 5  | null   | $.b[0]  | $.b  |
| 1   | 7     | integer | 7    | 6  | null   | $.b[1]  | $.b  |
| 2   | 8     | integer | 8    | 7  | null   | $.b[2]  | $.b  |
+-----+-------+---------+------+----+--------+---------+------+

Documento maior


Neste exemplo, usaremos um documento JSON maior. Primeiro, vamos chamar json_each() sem especificar um caminho:
SELECT * FROM json_each('[
        { 
        "user" : "Spike",
        "age" : 30,
        "scores" : [ 9, 7, 3 ]
        },
        { 
        "user" : "Faye",
        "age" : 25,
        "scores" : [ 90, 87, 93 ]
        },
        { 
        "user" : "Jet",
        "age" : 40,
        "scores" : [ 50, 38, 67 ]
        }
        ]'
    );

Resultado:

+-----+----------------------------------------------+--------+------+----+--------+---------+------+
| key |                    value                     |  type  | atom | id | parent | fullkey | path |
+-----+----------------------------------------------+--------+------+----+--------+---------+------+
| 0   | {"user":"Spike","age":30,"scores":[9,7,3]}   | object | N/A  | 1  | N/A    | $[0]    | $    |
| 1   | {"user":"Faye","age":25,"scores":[90,87,93]} | object | N/A  | 11 | N/A    | $[1]    | $    |
| 2   | {"user":"Jet","age":40,"scores":[50,38,67]}  | object | N/A  | 21 | N/A    | $[2]    | $    |
+-----+----------------------------------------------+--------+------+----+--------+---------+------+

Nesse caso, nosso valor JSON é um array que contém três objetos. Cada objeto é listado nos resultados.

Agora, vamos chamar json_each() novamente, mas desta vez vamos especificar um caminho:
SELECT * FROM json_each('[
        { 
        "user" : "Spike",
        "age" : 30,
        "scores" : [ 9, 7, 3 ]
        },
        { 
        "user" : "Faye",
        "age" : 25,
        "scores" : [ 90, 87, 93 ]
        },
        { 
        "user" : "Jet",
        "age" : 40,
        "scores" : [ 50, 38, 67 ]
        }
        ]',
        '$[1]'
    );

Resultado:

+--------+------------+---------+------+----+--------+-------------+------+
|  key   |   value    |  type   | atom | id | parent |   fullkey   | path |
+--------+------------+---------+------+----+--------+-------------+------+
| user   | Faye       | text    | Faye | 13 | null   | $[1].user   | $[1] |
| age    | 25         | integer | 25   | 15 | null   | $[1].age    | $[1] |
| scores | [90,87,93] | array   | null | 17 | null   | $[1].scores | $[1] |
+--------+------------+---------+------+----+--------+-------------+------+

Neste caso eu escolhi o segundo elemento do array especificando [1] (matrizes são zero com base em SQLite).

O resultado é que a saída contém informações sobre o segundo elemento da matriz.

Desta vez podemos ver que o path coluna contém $[1] .

Vamos mais fundo:
SELECT * FROM json_each('[
        { 
        "user" : "Spike",
        "age" : 30,
        "scores" : [ 9, 7, 3 ]
        },
        { 
        "user" : "Faye",
        "age" : 25,
        "scores" : [ 90, 87, 93 ]
        },
        { 
        "user" : "Jet",
        "age" : 40,
        "scores" : [ 50, 38, 67 ]
        }
        ]',
        '$[1].scores'
    );

Resultado:

+-----+-------+---------+------+----+--------+----------------+-------------+
| key | value |  type   | atom | id | parent |    fullkey     |    path     |
+-----+-------+---------+------+----+--------+----------------+-------------+
| 0   | 90    | integer | 90   | 18 | null   | $[1].scores[0] | $[1].scores |
| 1   | 87    | integer | 87   | 19 | null   | $[1].scores[1] | $[1].scores |
| 2   | 93    | integer | 93   | 20 | null   | $[1].scores[2] | $[1].scores |
+-----+-------+---------+------+----+--------+----------------+-------------+

Agora temos uma linha para cada elemento nas scores variedade.

Filtrando a consulta


Podemos modificar nossa consulta para filtrar os resultados com base em um determinado critério. Por exemplo:
SELECT 
    fullkey, 
    value 
FROM json_each('[
        { 
        "user" : "Spike",
        "age" : 30,
        "scores" : [ 9, 7, 3 ]
        },
        { 
        "user" : "Faye",
        "age" : 25,
        "scores" : [ 90, 87, 93 ]
        },
        { 
        "user" : "Jet",
        "age" : 40,
        "scores" : [ 50, 38, 67 ]
        }
        ]'
    )
WHERE json_each.value LIKE '%Faye%';

Resultado:

+---------+----------------------------------------------+
| fullkey |                    value                     |
+---------+----------------------------------------------+
| $[1]    | {"user":"Faye","age":25,"scores":[90,87,93]} |
+---------+----------------------------------------------+

Um exemplo de banco de dados


Suponha que temos a seguinte tabela:
SELECT * FROM guests;

Resultado:

+-------+--------------------------------------------------+
| guest |                      lunch                       |
+-------+--------------------------------------------------+
| Zohan | ["Beef Pie", "Fruit Salad", "Apple Juice"]       |
| Amy   | ["Vegetable Quiche", "Apple", "Fruit Juice"]     |
| Rohit | ["Beef Curry", "Dragonfruit", "Vegetable Juice"] |
| Igor  | ["Chicken Pie", "Jackfruit", "Fruit Juice"]      |
| Stacy | ["Chicken Curry", "Fruit Salad", "Apple Juice"]  |
| Aisha | ["Chicken Curry", "Apple Pie", "Apple Juice"]    |
+-------+--------------------------------------------------+

Esta tabela chamada guests tem duas colunas. A primeira coluna contém o nome do convidado e a segunda coluna contém o pedido do almoço. Eles podem pedir três pratos para o almoço. Seu pedido de almoço está na forma de uma matriz, onde cada prato é um elemento da matriz.

Aqui está um exemplo de execução de uma consulta que incorpora json_each() contra esta tabela:
SELECT DISTINCT
    guest,
    lunch
FROM 
    guests, 
    json_each(lunch)
WHERE json_each.value LIKE 'Apple Juice';

Resultado:

+-------+-------------------------------------------------+
| guest |                      lunch                      |
+-------+-------------------------------------------------+
| Zohan | ["Beef Pie", "Fruit Salad", "Apple Juice"]      |
| Stacy | ["Chicken Curry", "Fruit Salad", "Apple Juice"] |
| Aisha | ["Chicken Curry", "Apple Pie", "Apple Juice"]   |
+-------+-------------------------------------------------+

Aqui, devolvemos todos os convidados que pediram suco de maçã com o almoço, junto com o pedido completo do almoço.

Se quisermos devolver todos os convidados que pediram “algo” de maçã, podemos fazer isso:
SELECT DISTINCT
    guest,
    lunch
FROM 
    guests, 
    json_each(lunch)
WHERE json_each.value LIKE 'Apple%';

Resultado:

+-------+-------------------------------------------------+
| guest |                      lunch                      |
+-------+-------------------------------------------------+
| Zohan | ["Beef Pie", "Fruit Salad", "Apple Juice"]      |
| Amy   | ["Vegetable Quiche", "Apple", "Fruit Juice"]    |
| Stacy | ["Chicken Curry", "Fruit Salad", "Apple Juice"] |
| Aisha | ["Chicken Curry", "Apple Pie", "Apple Juice"]   |
+-------+-------------------------------------------------+

Observe que usei o DISTINCT cláusula na minha consulta. Isso garante que não recebamos várias linhas retornadas para o mesmo convidado. Para demonstrar o que quero dizer, aqui está a consulta novamente, mas sem o DISTINCT cláusula:
SELECT
    guest,
    lunch
FROM 
    guests, 
    json_each(lunch)
WHERE json_each.value LIKE 'Apple%';

Resultado:

+-------+-------------------------------------------------+
| guest |                      lunch                      |
+-------+-------------------------------------------------+
| Zohan | ["Beef Pie", "Fruit Salad", "Apple Juice"]      |
| Amy   | ["Vegetable Quiche", "Apple", "Fruit Juice"]    |
| Stacy | ["Chicken Curry", "Fruit Salad", "Apple Juice"] |
| Aisha | ["Chicken Curry", "Apple Pie", "Apple Juice"]   |
| Aisha | ["Chicken Curry", "Apple Pie", "Apple Juice"]   |
+-------+-------------------------------------------------+

Desta vez Aisha aparece duas vezes. Isso porque ela pediu dois pratos de maçã para o almoço – torta de maçã e suco de maçã.