sql >> Databasteknik >  >> RDS >> SQLite

SQLite JSON_EACH()

I SQLite, json_each() är en tabellvärderad funktion som följer JSON-värdet som det första argumentet och returnerar en tabell som består av en rad för varje arrayelement eller objektmedlem.

Vi tillhandahåller JSON-värdet som ett argument när vi anropar funktionen.

Vi kan valfritt skicka ett andra argument, som anger en sökväg att börja från. När vi gör detta, json_each() behandlar den banan som elementet på toppnivå.

json_each() funktion leder bara de omedelbara underordnade av arrayen eller objektet på översta nivån, eller bara själva toppnivåelementet om elementet på översta nivån är ett primitivt värde. För att rekursivt gå igenom JSON-understrukturen, använd json_tree() istället.

Syntax

Vi kan använda funktionen på följande sätt:

json_each(X)
json_each(X,P)

Där X representerar JSON och P är ett valfritt argument som representerar sökvägen att behandla som den översta nivån.

Exempel

Här är ett exempel för att visa hur det fungerar:

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

Resultat:

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

Vi kan se att varje objektmedlem har sin egen rad med lite användbar information, såsom dess typ (SQL-textvärde), sökväg, etc.

Angående id enligt SQLite-dokumentationen är detta ett internt hushållsnummer, vars beräkning kan ändras i framtida utgåvor. Den enda garantin är att id kolumnen kommer att vara olika för varje rad.

Den överordnade kolumnen är alltid null när du anropar json_each() . Den här kolumnen blir mer meningsfull när du använder json_tree() .

Array

I det här exemplet är JSON-värdet en array:

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

Resultat:

+-----+-------+---------+------+----+--------+---------+------+
| 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]    | $    |
+-----+-------+---------+------+----+--------+---------+------+

Ange en sökväg

Vi kan använda ett andra argument för att ange en sökväg som ska behandlas som den översta nivån.

Exempel:

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

Resultat:

+-----+-------+---------+------+----+--------+---------+------+
| 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  |
+-----+-------+---------+------+----+--------+---------+------+

Större dokument

I det här exemplet kommer vi att använda ett större JSON-dokument. Låt oss först anropa json_each() utan att ange en sökväg:

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 ]
        }
        ]'
    );

Resultat:

+-----+----------------------------------------------+--------+------+----+--------+---------+------+
| 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]    | $    |
+-----+----------------------------------------------+--------+------+----+--------+---------+------+

I det här fallet är vårt JSON-värde en array som innehåller tre objekt. Varje objekt listas i resultaten.

Låt oss nu anropa json_each() igen, men den här gången anger vi en sökväg:

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]'
    );

Resultat:

+--------+------------+---------+------+----+--------+-------------+------+
|  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] |
+--------+------------+---------+------+----+--------+-------------+------+

I det här fallet valde jag det andra matriselementet genom att ange [1] (matriser är nollbaserade i SQLite).

Resultatet är att utgången innehåller information om det andra arrayelementet.

Den här gången kan vi se att path kolumnen innehåller $[1] .

Låt oss gå djupare:

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'
    );

Resultat:

+-----+-------+---------+------+----+--------+----------------+-------------+
| 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 |
+-----+-------+---------+------+----+--------+----------------+-------------+

Nu får vi en rad för varje element i scores array.

Filtrera frågan

Vi kan modifiera vår fråga för att filtrera resultaten baserat på ett givet kriterium. Till exempel:

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%';

Resultat:

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

Ett databasexempel

Anta att vi har följande tabell:

SELECT * FROM guests;

Resultat:

+-------+--------------------------------------------------+
| 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"]    |
+-------+--------------------------------------------------+

Den här tabellen kallas guests har två kolumner. Den första kolumnen innehåller namnet på gästen, och den andra kolumnen innehåller deras lunchbeställning. De kan beställa tre rätter till lunch. Deras lunchbeställning är i form av en array, där varje rätt är ett element i arrayen.

Här är ett exempel på att köra en fråga som innehåller json_each() mot denna tabell:

SELECT DISTINCT
    guest,
    lunch
FROM 
    guests, 
    json_each(lunch)
WHERE json_each.value LIKE 'Apple Juice';

Resultat:

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

Här lämnade vi tillbaka alla gäster som beställt äppeljuice till sin lunch, tillsammans med sin fulla lunchbeställning.

Om vi ​​vill returnera alla gäster som beställt äpple "något", kan vi göra så här:

SELECT DISTINCT
    guest,
    lunch
FROM 
    guests, 
    json_each(lunch)
WHERE json_each.value LIKE 'Apple%';

Resultat:

+-------+-------------------------------------------------+
| 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"]   |
+-------+-------------------------------------------------+

Lägg märke till att jag använde DISTINCT klausul i min fråga. Detta säkerställer att vi inte får flera rader returnerade för samma gäst. För att visa vad jag menar, här är frågan igen, men utan DISTINCT klausul:

SELECT
    guest,
    lunch
FROM 
    guests, 
    json_each(lunch)
WHERE json_each.value LIKE 'Apple%';

Resultat:

+-------+-------------------------------------------------+
| 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"]   |
+-------+-------------------------------------------------+

Den här gången dyker Aisha upp två gånger. Det beror på att hon beställde två äppelrätter till lunch – Äppelpaj och Äppeljuice.


  1. Jämför två rader och identifiera kolumner vars värden är olika

  2. Oracle PL/SQL:DBMS_SCHEDULER.CREATE_JOB Exempel

  3. Konvertera ett datum i MySQL från strängfält

  4. Hur undviker man dela med noll-fel i SQL?