In SQLite, json_each()
ist eine Tabellenwertfunktion, die den als erstes Argument bereitgestellten JSON-Wert durchläuft und eine Tabelle zurückgibt, die aus einer Zeile für jedes Array-Element oder Objektmitglied besteht.
Wir geben den JSON-Wert als Argument an, wenn wir die Funktion aufrufen.
Wir können optional ein zweites Argument übergeben, das einen Startpfad angibt. Wenn wir dies tun, json_each()
behandelt diesen Pfad als Element der obersten Ebene.
Der json_each()
Die Funktion durchläuft nur die unmittelbar untergeordneten Elemente des Arrays oder Objekts der obersten Ebene oder nur das Element der obersten Ebene selbst, wenn das Element der obersten Ebene ein primitiver Wert ist. Um die JSON-Unterstruktur rekursiv zu durchlaufen, verwenden Sie json_tree()
stattdessen.
Syntax
Wir können die Funktion auf folgende Weise verwenden:
json_each(X)
json_each(X,P)
Wobei X
steht für JSON und P
ist ein optionales Argument, das den Pfad darstellt, der als oberste Ebene behandelt werden soll.
Beispiel
Hier ist ein Beispiel, um zu demonstrieren, wie es funktioniert:
SELECT * FROM json_each('{ "name" : "Woof", "age" : 10 }');
Ergebnis:
+------+-------+---------+------+----+--------+---------+------+ | key | value | type | atom | id | parent | fullkey | path | +------+-------+---------+------+----+--------+---------+------+ | name | Woof | text | Woof | 2 | null | $.name | $ | | age | 10 | integer | 10 | 4 | null | $.age | $ | +------+-------+---------+------+----+--------+---------+------+
Wir können sehen, dass jedes Objektmitglied eine eigene Zeile mit einigen nützlichen Informationen hat, wie z. B. Typ (SQL-Textwert), Pfad usw.
Bezüglich der id
-Spalte, laut SQLite-Dokumentation ist dies eine interne Verwaltungsnummer, deren Berechnung sich in zukünftigen Versionen ändern könnte. Die einzige Garantie ist, dass die id
Spalte wird für jede Zeile anders sein.
Die übergeordnete Spalte ist immer null
beim Aufruf von json_each()
. Diese Spalte wird aussagekräftiger, wenn json_tree()
verwendet wird .
Array
In diesem Beispiel ist der JSON-Wert ein Array:
SELECT * FROM json_each('[ 10, 30, 45 ]');
Ergebnis:
+-----+-------+---------+------+----+--------+---------+------+ | 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] | $ | +-----+-------+---------+------+----+--------+---------+------+
Geben Sie einen Pfad an
Wir können ein zweites Argument verwenden, um einen Pfad anzugeben, der als oberste Ebene behandelt werden soll.
Beispiel:
SELECT * FROM json_each('{ "a" : 1, "b" : [ 4, 7, 8 ] }', '$.b');
Ergebnis:
+-----+-------+---------+------+----+--------+---------+------+ | 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 | +-----+-------+---------+------+----+--------+---------+------+
Größeres Dokument
In diesem Beispiel verwenden wir ein größeres JSON-Dokument. Rufen wir zuerst json_each()
auf ohne Pfadangabe:
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 ]
}
]'
);
Ergebnis:
+-----+----------------------------------------------+--------+------+----+--------+---------+------+ | 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] | $ | +-----+----------------------------------------------+--------+------+----+--------+---------+------+
In diesem Fall ist unser JSON-Wert ein Array, das drei Objekte enthält. Jedes Objekt wird in den Ergebnissen aufgelistet.
Rufen wir nun json_each()
auf wieder, aber diesmal geben wir einen Pfad an:
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]'
);
Ergebnis:
+--------+------------+---------+------+----+--------+-------------+------+ | 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] | +--------+------------+---------+------+----+--------+-------------+------+
In diesem Fall habe ich das zweite Array-Element ausgewählt, indem ich [1]
angegeben habe (Arrays sind in SQLite nullbasiert).
Das Ergebnis ist, dass die Ausgabe Informationen über das zweite Array-Element enthält.
Dieses Mal können wir sehen, dass der Pfad
Spalte enthält $[1][code> .
Gehen wir tiefer:
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'
);
Ergebnis:
+-----+-------+---------+------+----+--------+----------------+-------------+ | 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 | +-----+-------+---------+------+----+--------+----------------+-------------+
Jetzt erhalten wir eine Zeile für jedes Element in den Ergebnissen
Array.
Filtern der Abfrage
Wir können unsere Abfrage ändern, um die Ergebnisse basierend auf einem bestimmten Kriterium zu filtern. Zum Beispiel:
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%';
Ergebnis:
+---------+----------------------------------------------+ | fullkey | value | +---------+----------------------------------------------+ | $[1] | {"user":"Faye","age":25,"scores":[90,87,93]} | +---------+----------------------------------------------+
Ein Datenbankbeispiel
Angenommen, wir haben die folgende Tabelle:
SELECT * FROM guests;
Ergebnis:
+-------+--------------------------------------------------+ | 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"] | +-------+--------------------------------------------------+
Diese Tabelle heißt guests
hat zwei Spalten. Die erste Spalte enthält den Namen des Gastes und die zweite Spalte enthält die Essensbestellung. Sie können drei Gerichte zum Mittagessen bestellen. Ihre Mittagsbestellung hat die Form eines Arrays, wobei jedes Gericht ein Element im Array ist.
Hier ist ein Beispiel für die Ausführung einer Abfrage, die json_each()
enthält gegen diese Tabelle:
SELECT DISTINCT
guest,
lunch
FROM
guests,
json_each(lunch)
WHERE json_each.value LIKE 'Apple Juice';
Ergebnis:
+-------+-------------------------------------------------+ | guest | lunch | +-------+-------------------------------------------------+ | Zohan | ["Beef Pie", "Fruit Salad", "Apple Juice"] | | Stacy | ["Chicken Curry", "Fruit Salad", "Apple Juice"] | | Aisha | ["Chicken Curry", "Apple Pie", "Apple Juice"] | +-------+-------------------------------------------------+
Hier haben wir alle Gäste zurückgegeben, die Apfelsaft zum Mittagessen bestellt haben, zusammen mit ihrer vollen Mittagsbestellung.
Wenn wir allen Gästen, die Apfel „etwas“ bestellt haben, zurückgeben möchten, könnten wir Folgendes tun:
SELECT DISTINCT
guest,
lunch
FROM
guests,
json_each(lunch)
WHERE json_each.value LIKE 'Apple%';
Ergebnis:
+-------+-------------------------------------------------+ | 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"] | +-------+-------------------------------------------------+
Beachten Sie, dass ich den DISTINCT
verwendet habe Klausel in meiner Abfrage. Dadurch wird sichergestellt, dass wir nicht mehrere Zeilen für denselben Gast zurückgeben. Um zu demonstrieren, was ich meine, hier noch einmal die Abfrage, aber ohne den DISTINCT
Klausel:
SELECT
guest,
lunch
FROM
guests,
json_each(lunch)
WHERE json_each.value LIKE 'Apple%';
Ergebnis:
+-------+-------------------------------------------------+ | 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"] | +-------+-------------------------------------------------+
Diesmal erscheint Aisha zweimal. Das liegt daran, dass sie zwei Apfelgerichte zum Mittagessen bestellt hat – Apfelkuchen und Apfelsaft.