sql >> Base de Datos >  >> RDS >> MariaDB

MariaDB JSON_TABLE() explicado

En MariaDB, JSON_TABLE() es una función integrada que convierte datos JSON en un formato relacional.

En otras palabras, te permite devolver un documento JSON como una tabla.

El JSON_TABLE() La función se introdujo en MariaDB 10.6.0.

Sintaxis

La sintaxis es así:

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

Donde column_list va así:

column[, column][, ...]

Donde column va así:

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)

Donde on_empty va así:

{NULL | DEFAULT string | ERROR} ON EMPTY

Y on_error va así:

{NULL | DEFAULT string | ERROR} ON ERROR

Ejemplo

Aquí hay un ejemplo para demostrarlo.

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;

Resultado:

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

Aquí, nombramos cada columna de la tabla, especificamos su tipo de datos y luego especificamos la ruta del documento JSON que se aplicará a esa columna.

Entonces, llamamos a nuestra primera columna name y luego asignó el nodo llamado name del documento JSON a esa columna.

Columnas de ordinalidad

El FOR ORDINALITY La opción se puede usar para contar las filas, comenzando desde 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;

Resultado:

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

Comprobación de la existencia de una ruta

Puedes usar el EXISTS cláusula para verificar la existencia de una ruta. Si la ruta existe en el documento JSON, el resultado es 1 . Si no existe, 0 es devuelto.

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;

Resultado:

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

Rutas anidadas

La NESTED PATH cláusula le permite tratar con documentos JSON anidados. Cuando usa esta cláusula, convierte estructuras JSON anidadas en varias filas.

Ejemplo:

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;

Resultado:

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

Lidiando con caminos vacíos

El ON EMPTY La cláusula especifica lo que se hará cuando el elemento especificado por la ruta de búsqueda falte en el documento JSON.

Ejemplo:

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;

Resultado:

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

En este ejemplo, Ruff no tiene un campo de tipo y, por lo tanto, N/A es regresado. Esto se debe a que lo especifiqué en ON EMPTY cláusula para ese campo.

Lidiar con los errores

El ON ERROR La cláusula especifica qué se debe hacer si se produce un error de estructura JSON al intentar extraer el valor del documento.

Un error de estructura JSON ocurre solo cuando intenta convertir un JSON no escalar (matriz u objeto) en un valor escalar. Cuando ON ERROR la cláusula no está presente, NULL ON ERROR está implícito.

Aquí hay un ejemplo de cómo manejar un error de estructura JSON:

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;

Resultado:

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

Aquí, especifiqué una cadena (Oops! ) para usar cada vez que se produzca un error de estructura JSON.

En este caso, también incluí el ON EMPTY cláusula. Esto demuestra que tanto el ON ERROR y el ON EMPTY cláusula se puede utilizar en la misma declaración.

Sin embargo, es importante tener en cuenta que un error de conversión de tipo de datos (por ejemplo, un intento de almacenar un valor no entero en un campo de enteros, o una columna varchar que se trunca) no se considera un error JSON y, por lo tanto, no activará el ON ERROR cláusula. En su lugar, generará advertencias.

He aquí un ejemplo para ilustrar lo que quiero decir:

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;

Resultado:

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

Mostremos las advertencias:

SHOW WARNINGS;

Resultado:

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