sql >> Database teknologi >  >> RDS >> SQLite

SQLite JSON_TREE()

I SQLite, json_tree() er en tabelværdi-funktion, der følger den JSON-værdi, der er angivet som dets første argument, og returnerer en tabel bestående af en række for hvert array-element eller objektmedlem.

Vi angiver JSON-værdien som et argument, når vi kalder funktionen.

Vi kan valgfrit sende et andet argument, som specificerer en sti at starte fra. Når vi gør dette, json_tree() behandler denne vej som elementet på øverste niveau.

json_tree() funktion går rekursivt gennem JSON-understrukturen begyndende med elementet på øverste niveau. Brug json_each() for kun at gå de umiddelbare børn af arrayet eller objektet på øverste niveau, eller bare selve elementet på øverste niveau, hvis elementet på øverste niveau er en primitiv værdi funktion i stedet for.

Syntaks

Vi kan bruge json_tree() fungerer på følgende måder:

json_tree(X)
json_tree(X,P)

Hvor X repræsenterer JSON og P er et valgfrit argument, der repræsenterer stien, der skal behandles som det øverste niveau.

Eksempel

Her er et eksempel for at demonstrere, hvordan det virker:

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

Resultat:

+------+--------------------------+---------+------+----+--------+---------+------+
| key  |          value           |  type   | atom | id | parent | fullkey | path |
+------+--------------------------+---------+------+----+--------+---------+------+
| null | {"name":"Woof","age":10} | object  | null | 0  | null   | $       | $    |
| name | Woof                     | text    | Woof | 2  | 0      | $.name  | $    |
| age  | 10                       | integer | 10   | 4  | 0      | $.age   | $    |
+------+--------------------------+---------+------+----+--------+---------+------+

Vi kan se, at hvert objektmedlem har sin egen række med nogle nyttige oplysninger, såsom dens type (SQL-tekstværdi), sti osv.

Med hensyn til id kolonne, ifølge SQLite-dokumentationen er dette et internt husholdningsnummer, hvis beregning kan ændre sig i fremtidige udgivelser. Den eneste garanti er, at id kolonne vil være forskellig for hver række.

Array

I dette eksempel er JSON-værdien en matrix:

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

Resultat:

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

Angiv en sti

Vi kan bruge et andet argument til at angive en sti, der skal behandles som det øverste niveau.

Eksempel:

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

Resultat:

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

Større dokument

I dette eksempel bruger vi et større JSON-dokument. Lad os først kalde json_tree() uden at angive en sti:

SELECT * FROM json_tree('[
        { 
        "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     |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| null   | [{"user":"Spike","age":30,"scores":[9,7,3]},{"user":"Faye"," | array   | null  | 0    | null   | $              | $           |
| null   | age":25,"scores":[90,87,93]},{"user":"Jet","age":40,"scores  | null    | null  | null | null   | null           | null        |
| null   | ":[50,38,67]}]                                               | null    | null  | null | null   | null           | null        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 0      | {"user":"Spike","age":30,"scores":[9,7,3]}                   | object  | null  | 1    | 0      | $[0]           | $           |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| user   | Spike                                                        | text    | Spike | 3    | 1      | $[0].user      | $[0]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| age    | 30                                                           | integer | 30    | 5    | 1      | $[0].age       | $[0]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| scores | [9,7,3]                                                      | array   | null  | 7    | 1      | $[0].scores    | $[0]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 0      | 9                                                            | integer | 9     | 8    | 7      | $[0].scores[0] | $[0].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 1      | 7                                                            | integer | 7     | 9    | 7      | $[0].scores[1] | $[0].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 2      | 3                                                            | integer | 3     | 10   | 7      | $[0].scores[2] | $[0].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 1      | {"user":"Faye","age":25,"scores":[90,87,93]}                 | object  | null  | 11   | 0      | $[1]           | $           |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| user   | Faye                                                         | text    | Faye  | 13   | 11     | $[1].user      | $[1]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| age    | 25                                                           | integer | 25    | 15   | 11     | $[1].age       | $[1]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| scores | [90,87,93]                                                   | array   | null  | 17   | 11     | $[1].scores    | $[1]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 0      | 90                                                           | integer | 90    | 18   | 17     | $[1].scores[0] | $[1].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 1      | 87                                                           | integer | 87    | 19   | 17     | $[1].scores[1] | $[1].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 2      | 93                                                           | integer | 93    | 20   | 17     | $[1].scores[2] | $[1].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 2      | {"user":"Jet","age":40,"scores":[50,38,67]}                  | object  | null  | 21   | 0      | $[2]           | $           |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| user   | Jet                                                          | text    | Jet   | 23   | 21     | $[2].user      | $[2]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| age    | 40                                                           | integer | 40    | 25   | 21     | $[2].age       | $[2]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| scores | [50,38,67]                                                   | array   | null  | 27   | 21     | $[2].scores    | $[2]        |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 0      | 50                                                           | integer | 50    | 28   | 27     | $[2].scores[0] | $[2].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 1      | 38                                                           | integer | 38    | 29   | 27     | $[2].scores[1] | $[2].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+
| 2      | 67                                                           | integer | 67    | 30   | 27     | $[2].scores[2] | $[2].scores |
+--------+--------------------------------------------------------------+---------+-------+------+--------+----------------+-------------+

I dette tilfælde er vores JSON-værdi et array, der indeholder tre objekter. Hvert objekt er opført i resultaterne, og hvert af disse objekters medlemmer er angivet sammen med deres respektive værdier og så videre.

Lad os nu kalde json_tree() igen, men denne gang angiver vi en sti:

SELECT * FROM json_tree('[
        { 
        "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     |
+--------+----------------------------------------------+---------+------+----+--------+----------------+-------------+
| null   | {"user":"Faye","age":25,"scores":[90,87,93]} | object  | null | 11 | null   | $[0]           | $           |
| user   | Faye                                         | text    | Faye | 13 | 11     | $[0].user      | $[0]        |
| age    | 25                                           | integer | 25   | 15 | 11     | $[0].age       | $[0]        |
| scores | [90,87,93]                                   | array   | null | 17 | 11     | $[0].scores    | $[0]        |
| 0      | 90                                           | integer | 90   | 18 | 17     | $[0].scores[0] | $[0].scores |
| 1      | 87                                           | integer | 87   | 19 | 17     | $[0].scores[1] | $[0].scores |
| 2      | 93                                           | integer | 93   | 20 | 17     | $[0].scores[2] | $[0].scores |
+--------+----------------------------------------------+---------+------+----+--------+----------------+-------------+

I dette tilfælde valgte jeg det andet array-element ved at angive [1] (arrays er nul baseret i SQLite).

Resultatet er, at træet kun er begrænset til det andet array-element.

Lad os gå dybere:

SELECT * FROM json_tree('[
        { 
        "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     |
+--------+------------+---------+------+----+--------+----------------+-------------+
| scores | [90,87,93] | array   | null | 17 | null   | $[0].scores    | $[0]        |
| 0      | 90         | integer | 90   | 18 | 17     | $[0].scores[0] | $[0].scores |
| 1      | 87         | integer | 87   | 19 | 17     | $[0].scores[1] | $[0].scores |
| 2      | 93         | integer | 93   | 20 | 17     | $[0].scores[2] | $[0].scores |
+--------+------------+---------+------+----+--------+----------------+-------------+

Jo dybere vi går, jo færre rækker returneres. Det er fordi vi kun får et træ, der starter ved den specifikke sti, som vi har angivet.

Filtrering af forespørgslen

Vi kan ændre vores forespørgsel for at filtrere resultaterne ud fra et givet kriterium. For eksempel:

SELECT 
    fullkey, 
    value 
FROM json_tree('[
        { 
        "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_tree.value LIKE '%Faye%';

Resultat:

+-----------+--------------------------------------------------------------+
|  fullkey  |                            value                             |
+-----------+--------------------------------------------------------------+
| $         | [{"user":"Spike","age":30,"scores":[9,7,3]},{"user":"Faye"," |
| null      | age":25,"scores":[90,87,93]},{"user":"Jet","age":40,"scores  |
| null      | ":[50,38,67]}]                                               |
+-----------+--------------------------------------------------------------+
| $[1]      | {"user":"Faye","age":25,"scores":[90,87,93]}                 |
+-----------+--------------------------------------------------------------+
| $[1].user | Faye                                                         |
+-----------+--------------------------------------------------------------+

Vi kan kun returnere den sidste række ved at gøre dette:

SELECT *
FROM json_tree('[
        { 
        "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_tree.value = 'Faye';

Resultat:

+------+-------+------+------+----+--------+-----------+------+
| key  | value | type | atom | id | parent |  fullkey  | path |
+------+-------+------+------+----+--------+-----------+------+
| user | Faye  | text | Faye | 13 | 11     | $[1].user | $[1] |
+------+-------+------+------+----+--------+-----------+------+

Returbladsknuder

Vi kan begrænse resultaterne til kun bladknuder, hvis vi vil. Med "bladknuder" mener jeg kun de nøgler, der ikke har yderligere underordnede elementer.

Der er et par måder at gøre dette på.

En mulighed er at filtrere alle objekter og arrays fra:

SELECT * 
FROM json_tree('[
        { 
        "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_tree.type NOT IN ('object','array');

Resultat:

+------+-------+---------+-------+----+--------+----------------+-------------+
| key  | value |  type   | atom  | id | parent |    fullkey     |    path     |
+------+-------+---------+-------+----+--------+----------------+-------------+
| user | Spike | text    | Spike | 3  | 1      | $[0].user      | $[0]        |
| age  | 30    | integer | 30    | 5  | 1      | $[0].age       | $[0]        |
| 0    | 9     | integer | 9     | 8  | 7      | $[0].scores[0] | $[0].scores |
| 1    | 7     | integer | 7     | 9  | 7      | $[0].scores[1] | $[0].scores |
| 2    | 3     | integer | 3     | 10 | 7      | $[0].scores[2] | $[0].scores |
| user | Faye  | text    | Faye  | 13 | 11     | $[1].user      | $[1]        |
| age  | 25    | integer | 25    | 15 | 11     | $[1].age       | $[1]        |
| 0    | 90    | integer | 90    | 18 | 17     | $[1].scores[0] | $[1].scores |
| 1    | 87    | integer | 87    | 19 | 17     | $[1].scores[1] | $[1].scores |
| 2    | 93    | integer | 93    | 20 | 17     | $[1].scores[2] | $[1].scores |
| user | Jet   | text    | Jet   | 23 | 21     | $[2].user      | $[2]        |
| age  | 40    | integer | 40    | 25 | 21     | $[2].age       | $[2]        |
| 0    | 50    | integer | 50    | 28 | 27     | $[2].scores[0] | $[2].scores |
| 1    | 38    | integer | 38    | 29 | 27     | $[2].scores[1] | $[2].scores |
| 2    | 67    | integer | 67    | 30 | 27     | $[2].scores[2] | $[2].scores |
+------+-------+---------+-------+----+--------+----------------+-------------+

En anden måde at gøre det på er at tjekke atom kolonne for nulværdier. Specifikt returnerer vi kun rækker, hvor denne kolonne doesn't indeholde en null-værdi:

SELECT * 
FROM json_tree('[
        { 
        "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 atom IS NOT NULL;

Resultat:

+------+-------+---------+-------+----+--------+----------------+-------------+
| key  | value |  type   | atom  | id | parent |    fullkey     |    path     |
+------+-------+---------+-------+----+--------+----------------+-------------+
| user | Spike | text    | Spike | 3  | 1      | $[0].user      | $[0]        |
| age  | 30    | integer | 30    | 5  | 1      | $[0].age       | $[0]        |
| 0    | 9     | integer | 9     | 8  | 7      | $[0].scores[0] | $[0].scores |
| 1    | 7     | integer | 7     | 9  | 7      | $[0].scores[1] | $[0].scores |
| 2    | 3     | integer | 3     | 10 | 7      | $[0].scores[2] | $[0].scores |
| user | Faye  | text    | Faye  | 13 | 11     | $[1].user      | $[1]        |
| age  | 25    | integer | 25    | 15 | 11     | $[1].age       | $[1]        |
| 0    | 90    | integer | 90    | 18 | 17     | $[1].scores[0] | $[1].scores |
| 1    | 87    | integer | 87    | 19 | 17     | $[1].scores[1] | $[1].scores |
| 2    | 93    | integer | 93    | 20 | 17     | $[1].scores[2] | $[1].scores |
| user | Jet   | text    | Jet   | 23 | 21     | $[2].user      | $[2]        |
| age  | 40    | integer | 40    | 25 | 21     | $[2].age       | $[2]        |
| 0    | 50    | integer | 50    | 28 | 27     | $[2].scores[0] | $[2].scores |
| 1    | 38    | integer | 38    | 29 | 27     | $[2].scores[1] | $[2].scores |
| 2    | 67    | integer | 67    | 30 | 27     | $[2].scores[2] | $[2].scores |
+------+-------+---------+-------+----+--------+----------------+-------------+

atom kolonne er den SQL-værdi, der svarer til primitive elementer - andre elementer end JSON-arrays og -objekter. Denne kolonne er altid null for et JSON-array eller et objekt. value kolonnen er den samme som atom kolonne for primitive JSON-elementer, men overtager tekstens JSON-værdi for arrays og objekter.

Et databaseeksempel

Antag, at vi har følgende tabel:

SELECT * FROM scores;

Resultat:

+---------+---------------------------------------------------------+
| teacher |                        students                         |
+---------+---------------------------------------------------------+
| Zohan   | [{"Amy":[10,8,9]},{"Josh":[3,2,4]},{"Igor":[7,6,5]}]    |
| Stacy   | [{"Pete":[5,3,1]},{"Liz":[5,8,7]},{"Jet":[9,5,7]}]      |
| Aisha   | [{"Zolton":[4,6,7]},{"Bree":[7,7,4]},{"Rohit":[9,8,8]}] |
+---------+---------------------------------------------------------+

Denne tabel kaldet scores har to kolonner. Den første kolonne indeholder navnet på læreren, og den anden kolonne indeholder et JSON-dokument. JSON-dokumentet indeholder elever og deres resultater.

Her er et eksempel på at køre en forespørgsel, der bruger json_tree() mod denne tabel:

SELECT
    teacher,
    key AS student,
    value
FROM 
    scores, 
    json_tree(students, '$[1].Liz')
WHERE json_tree.key = 'Liz';

Resultat:

+---------+---------+---------+
| teacher | student |  value  |
+---------+---------+---------+
| Stacy   | Liz     | [5,8,7] |
+---------+---------+---------+

Her returnerede vi alle scoringer til Liz, og vi returnerede også hendes lærer.

Følgende forespørgsel returnerer hendes anden score:

SELECT
    teacher,
    key AS student,
    value AS score
FROM 
    scores, 
    json_tree(students, '$[1].Liz')
WHERE json_tree.key = 1;

Resultat:

+---------+---------+-------+
| teacher | student | score |
+---------+---------+-------+
| Stacy   | 1       | 8     |
+---------+---------+-------+

  1. Sådan opsætter du Oracle EBS Auditing

  2. Installer flere MySQL-instanser på en Linux-server - brug en separat MySQL-konfigurationsfil

  3. Hvad er forskellen mellem primært indeks og sekundært indeks nøjagtigt?

  4. Oracle - Materialized View stadig tilgængelig under fuldstændig opdatering. Hvordan virker det?