V SQLite, json_each()
je funkce s hodnotou tabulky, která prochází hodnotou JSON poskytnutou jako její první argument a vrací tabulku skládající se z jednoho řádku pro každý prvek pole nebo člen objektu.
Při volání funkce poskytujeme jako argument hodnotu JSON.
Volitelně můžeme předat druhý argument, který určuje cestu, ze které se má začít. Když to uděláme, json_each()
považuje tuto cestu za prvek nejvyšší úrovně.
json_each()
funkce prochází pouze bezprostřední potomky pole nebo objektu nejvyšší úrovně nebo pouze samotný prvek nejvyšší úrovně, pokud je prvkem nejvyšší úrovně primitivní hodnota. Chcete-li rekurzivně projít podstrukturou JSON, použijte json_tree()
místo toho.
Syntaxe
Funkci můžeme použít následujícími způsoby:
json_each(X)
json_each(X,P)
Kde X
představuje JSON a P
je volitelný argument, který představuje cestu, která má být považována za nejvyšší úroveň.
Příklad
Zde je příklad demonstrující, jak to funguje:
SELECT * FROM json_each('{ "name" : "Woof", "age" : 10 }');
Výsledek:
+------+-------+---------+------+----+--------+---------+------+ | key | value | type | atom | id | parent | fullkey | path | +------+-------+---------+------+----+--------+---------+------+ | name | Woof | text | Woof | 2 | null | $.name | $ | | age | 10 | integer | 10 | 4 | null | $.age | $ | +------+-------+---------+------+----+--------+---------+------+
Vidíme, že každý člen objektu má svůj vlastní řádek s některými užitečnými informacemi, jako je jeho typ (hodnota textu SQL), cesta atd.
Pokud jde o id
sloupec, podle dokumentace SQLite se jedná o interní úklidové číslo, jehož výpočet se může v budoucích verzích změnit. Jedinou zárukou je, že id
sloupec se bude pro každý řádek lišit.
Nadřazený sloupec je vždy null
při volání json_each()
. Tento sloupec nabývá na smysluplnosti při použití json_tree()
.
Pole
V tomto příkladu je hodnotou JSON pole:
SELECT * FROM json_each('[ 10, 30, 45 ]');
Výsledek:
+-----+-------+---------+------+----+--------+---------+------+ | 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] | $ | +-----+-------+---------+------+----+--------+---------+------+
Zadejte cestu
Můžeme použít druhý argument k určení cesty, která se má považovat za nejvyšší úroveň.
Příklad:
SELECT * FROM json_each('{ "a" : 1, "b" : [ 4, 7, 8 ] }', '$.b');
Výsledek:
+-----+-------+---------+------+----+--------+---------+------+ | 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 | +-----+-------+---------+------+----+--------+---------+------+
Větší dokument
V tomto příkladu použijeme větší dokument JSON. Nejprve zavolejte json_each()
bez zadání cesty:
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 ]
}
]'
);
Výsledek:
+-----+----------------------------------------------+--------+------+----+--------+---------+------+ | 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] | $ | +-----+----------------------------------------------+--------+------+----+--------+---------+------+
V tomto případě je naší hodnotou JSON pole, které obsahuje tři objekty. Každý objekt je uveden ve výsledcích.
Nyní zavolejte json_each()
znovu, ale tentokrát zadáme cestu:
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]'
);
Výsledek:
+--------+------------+---------+------+----+--------+-------------+------+ | 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] | +--------+------------+---------+------+----+--------+-------------+------+
V tomto případě jsem zvolil druhý prvek pole zadáním [1]
(pole jsou v SQLite založeny na nule).
Výsledkem je, že výstup obsahuje informace o druhém prvku pole.
Tentokrát vidíme, že path
sloupec obsahuje $[1]
.
Pojďme hlouběji:
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'
);
Výsledek:
+-----+-------+---------+------+----+--------+----------------+-------------+ | 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 | +-----+-------+---------+------+----+--------+----------------+-------------+
Nyní dostaneme řádek pro každý prvek v scores
pole.
Filtrování dotazu
Náš dotaz můžeme upravit tak, aby filtroval výsledky na základě daných kritérií. Například:
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%';
Výsledek:
+---------+----------------------------------------------+ | fullkey | value | +---------+----------------------------------------------+ | $[1] | {"user":"Faye","age":25,"scores":[90,87,93]} | +---------+----------------------------------------------+
Příklad databáze
Předpokládejme, že máme následující tabulku:
SELECT * FROM guests;
Výsledek:
+-------+--------------------------------------------------+ | 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"] | +-------+--------------------------------------------------+
Tato tabulka se nazývá guests
má dva sloupce. První sloupec obsahuje jméno hosta a druhý sloupec jeho objednávku oběda. K obědu si mohou objednat tři jídla. Jejich obědová objednávka je ve formě pole, kde každé jídlo je prvkem v poli.
Zde je příklad spuštění dotazu, který obsahuje json_each()
proti této tabulce:
SELECT DISTINCT
guest,
lunch
FROM
guests,
json_each(lunch)
WHERE json_each.value LIKE 'Apple Juice';
Výsledek:
+-------+-------------------------------------------------+ | guest | lunch | +-------+-------------------------------------------------+ | Zohan | ["Beef Pie", "Fruit Salad", "Apple Juice"] | | Stacy | ["Chicken Curry", "Fruit Salad", "Apple Juice"] | | Aisha | ["Chicken Curry", "Apple Pie", "Apple Juice"] | +-------+-------------------------------------------------+
Zde jsme vrátili všechny hosty, kteří si k obědu objednali jablečný džus, spolu s kompletní objednávkou oběda.
Pokud chceme vrátit všechny hosty, kteří si objednali jablečné „něco“, můžeme udělat toto:
SELECT DISTINCT
guest,
lunch
FROM
guests,
json_each(lunch)
WHERE json_each.value LIKE 'Apple%';
Výsledek:
+-------+-------------------------------------------------+ | 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"] | +-------+-------------------------------------------------+
Všimněte si, že jsem použil DISTINCT
klauzule v mém dotazu. To zajišťuje, že se nám nevrátí více řádků pro stejného hosta. Abych demonstroval, co tím myslím, zde je dotaz znovu, ale bez DISTINCT
klauzule:
SELECT
guest,
lunch
FROM
guests,
json_each(lunch)
WHERE json_each.value LIKE 'Apple%';
Výsledek:
+-------+-------------------------------------------------+ | 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"] | +-------+-------------------------------------------------+
Tentokrát se Aisha objeví dvakrát. To proto, že si k obědu objednala dvě jablečná jídla – Apple Pie a Apple Juice.