sql >> Databasteknik >  >> RDS >> MariaDB

MariaDB JSON_TABLE() Förklarad

I MariaDB, JSON_TABLE() är en inbyggd funktion som konverterar JSON-data till en relationsform.

Med andra ord låter den dig returnera ett JSON-dokument som en tabell.

JSON_TABLE() funktion introducerades i MariaDB 10.6.0.

Syntax

Syntaxen ser ut så här:

JSON_TABLE(json_doc, 
          context_path COLUMNS (column_list)
) [AS] alias

Där column_list går så här:

column[, column][, ...]

Där kolumn går så här:

name FOR ORDINALITY
    |  name type PATH value_path path [on_empty] [on_error]
    |  name type EXISTS PATH value_path
    |  NESTED [PATH] path COLUMNS (column_list)

Där on_empty går så här:

{NULL | DEFAULT string | ERROR} ON EMPTY

Och on_error går så här:

{NULL | DEFAULT string | ERROR} ON ERROR

Exempel

Här är ett exempel att visa.

SET @json_document = '
[
    { "name": "Wag", "type": "Dog", "weight": 20 },
    { "name": "Bark", "type": "Dog", "weight": 10 },
    { "name": "Meow", "type": "Cat", "weight": 7 }
]
';

SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    name VARCHAR(255) PATH '$.name', 
    type VARCHAR(50) PATH '$.type',
    weight INT PATH '$.weight' 
    )
) AS json_table;

Resultat:

+------+------+--------+
| name | type | weight |
+------+------+--------+
| Wag  | Dog  |     20 |
| Bark | Dog  |     10 |
| Meow | Cat  |      7 |
+------+------+--------+

Här namnger vi varje kolumn för tabellen, anger dess datatyp och anger sedan sökvägen från JSON-dokumentet som ska gälla för den kolumnen.

Så vi kallade vår första kolumn name , och mappade sedan noden som heter name från JSON-dokumentet till den kolumnen.

Ordinalitetskolumner

FOR ORDINALITY alternativet kan användas för att räkna raderna, med start från 1 .

SET @json_document = '
[
    { "name": "Scratch", "type": "Cat", "weight": 8 },
    { "name": "Bruce", "type": "Kangaroo", "weight": 100 },
    { "name": "Hop", "type": "Kangaroo", "weight": 130 }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    id FOR ORDINALITY,
    name VARCHAR(255) PATH '$.name', 
    type VARCHAR(50) PATH '$.type',
    weight INT PATH '$.weight' 
    )
) AS json_table;

Resultat:

+------+---------+----------+--------+
| id   | name    | type     | weight |
+------+---------+----------+--------+
|    1 | Scratch | Cat      |      8 |
|    2 | Bruce   | Kangaroo |    100 |
|    3 | Hop     | Kangaroo |    130 |
+------+---------+----------+--------+

Kontrollera att det finns en sökväg

Du kan använda EXISTS klausul för att kontrollera om det finns en sökväg. Om sökvägen finns i JSON-dokumentet är resultatet 1 . Om det inte finns, 0 returneras.

SET @json_document = '
[
    { "name": "Punch", "type": "Kangaroo", "weight": 200 },
    { "name": "Snap", "type": "Cat", "weight": 12 },
    { "name": "Ruff", "type": "Dog" }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    name  VARCHAR(255) PATH '$.name', 
    type VARCHAR(50) PATH '$.type',
    has_weight INT EXISTS PATH '$.weight' 
    )
) AS json_table;

Resultat:

+-------+----------+------------+
| name  | type     | has_weight |
+-------+----------+------------+
| Punch | Kangaroo |          1 |
| Snap  | Cat      |          1 |
| Ruff  | Dog      |          0 |
+-------+----------+------------+

Inkapslade vägar

Den NESTED PATH sats låter dig hantera kapslade JSON-dokument. När du använder den här satsen konverterar den kapslade JSON-strukturer till flera rader.

Exempel:

SET @json_document = '
[
    { "product": "Left Handed Screwdriver", "sizes": [ "S", "M", "L" ] },
    { "product": "Long Weight", "sizes": [ "S", "L", "XL" ] },
    { "product": "Bottomless Coffee Cup" }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    product  VARCHAR(255) PATH '$.product', 
    NESTED PATH '$.sizes[*]' columns (
        size VARCHAR(2) PATH '$'
        )
    )
) AS json_table;

Resultat:

+-------------------------+------+
| product                 | size |
+-------------------------+------+
| Left Handed Screwdriver | S    |
| Left Handed Screwdriver | M    |
| Left Handed Screwdriver | L    |
| Long Weight             | S    |
| Long Weight             | L    |
| Long Weight             | XL   |
| Bottomless Coffee Cup   | NULL |
+-------------------------+------+

Hantera tomma vägar

ON EMPTY sats anger vad som kommer att göras när elementet som anges av sökvägen saknas i JSON-dokumentet.

Exempel:

SET @json_document = '
[
    { "name": "Punch", "type": "Kangaroo", "weight": 200 },
    { "name": "Snap", "type": "Cat", "weight": 12 },
    { "name": "Ruff"}
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    name  VARCHAR(255) PATH '$.name', 
    type VARCHAR(50) PATH '$.type' DEFAULT "N/A" ON EMPTY,
    weight INT PATH '$.weight'
    )
) AS json_table;

Resultat:

+-------+----------+--------+
| name  | type     | weight |
+-------+----------+--------+
| Punch | Kangaroo |    200 |
| Snap  | Cat      |     12 |
| Ruff  | N/A      |   NULL |
+-------+----------+--------+

I det här exemplet, Ruff har inget typfält och därför N/A returneras. Detta beror på att jag angav det i ON EMPTY klausul för det fältet.

Hantera fel

ON ERROR sats anger vad som ska göras om ett JSON-strukturfel uppstår när man försöker extrahera värdet från dokumentet.

Ett JSON-strukturfel uppstår endast när du försöker konvertera en icke-skalär JSON (matris eller objekt) till ett skalärt värde. När ON ERROR klausul finns inte, NULL ON ERROR är underförstått.

Här är ett exempel på att hantera ett JSON-strukturfel:

SET @json_document = '
[
    { "product": "Left Handed Screwdriver", "sizes": [ "S", "M", "L" ] },
    { "product": "Long Weight", "sizes": [ "S", "L", "XL" ] },
    { "product": "Bottomless Coffee Cup" }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    product  VARCHAR(255) PATH '$.product', 
    sizes VARCHAR(5) PATH '$.sizes' 
        DEFAULT 'Oops!' ON ERROR
        DEFAULT 'None' ON EMPTY
    )
) AS json_table;

Resultat:

+-------------------------+-------+
| product                 | sizes |
+-------------------------+-------+
| Left Handed Screwdriver | Oops! |
| Long Weight             | Oops! |
| Bottomless Coffee Cup   | None  |
+-------------------------+-------+

Här angav jag en sträng (Hoppsan! ) att använda när ett JSON-strukturfel inträffade.

I det här fallet inkluderade jag även ON EMPTY klausul. Detta visar att både ON ERROR och ON EMPTY sats kan användas i samma sats.

Det är dock viktigt att notera att ett datatypkonverteringsfel (till exempel ett försök att lagra ett icke-heltalsvärde i ett heltalsfält eller en varchar kolumn som trunkeras) inte anses vara ett JSON-fel och kommer därför inte att utlösa PÅ FEL klausul. Istället kommer det att producera varningar.

Här är ett exempel för att illustrera vad jag menar:

SET @json_document = '
[
    { "name": "Punch", "type": "Kangaroo" },
    { "name": "Snap", "type": "Cat" },
    { "name": "Ruff", "type": "Dog" }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    name  VARCHAR(255) PATH '$.name', 
    type INT PATH '$.type' DEFAULT 'Oops!' ON ERROR
    )
) AS json_table;

Resultat:

+-------+------+
| name  | type |
+-------+------+
| Punch |    0 |
| Snap  |    0 |
| Ruff  |    0 |
+-------+------+
3 rows in set, 3 warnings (0.000 sec)

Låt oss visa varningarna:

SHOW WARNINGS;

Resultat:

+---------+------+---------------------------------------------------------------------------------+
| Level   | Code | Message                                                                         |
+---------+------+---------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'Kangaroo' for column ``.`(temporary)`.`type` at row 1 |
| Warning | 1366 | Incorrect integer value: 'Cat' for column ``.`(temporary)`.`type` at row 2      |
| Warning | 1366 | Incorrect integer value: 'Dog' for column ``.`(temporary)`.`type` at row 3      |
+---------+------+---------------------------------------------------------------------------------+

  1. få nytt SQL-post-ID

  2. Android Room Embedded Relation ignorerar SQL where-villkor

  3. LADDA DATAINFIL konvertera enkelt ÅÅÅÅMMDD till ÅÅÅÅ-MM-DD?

  4. PostgreSQL:Unik överträdelse:7 FEL:dubblettnyckelvärde bryter mot unika begränsningar users_pkey