JSON_TABLE

2024-04-19 08:42:50  Updated

Purpose

JSON_TABLE() converts semi-structured JSON data into structured data. That is, the function extracts data from a JSON document and returns it as a relational table with specified columns.

JSON_TABLE() provides column output for each JSON value, and provides multi-row (multi-column) output for a JSON array.

Syntax

JSON_TABLE(expr, path_literal COLUMNS (column_list)) [AS] alias

column_list:
    column[, column...]

column:
    column_name FOR ORDINALITY
    | column_name data_type PATH path_literal [json_value_on_empty_clause] [json_value_on_error_clause]
    | column_name data_type EXISTS PATH path_literal
    | NESTED [PATH] path_literal COLUMNS (column_list)

json_value_on_empty_clause:
    {NULL | DEFAULT json_string | ERROR} ON EMPTY

json_value_on_error_clause:
    {NULL | DEFAULT json_string | ERROR} ON ERROR

Description

JSON_TABLE() must be used in the FROM clause of a SELECT statement.

The parameters in the syntax are described as follows:

  • expr: the expression that evaluates to JSON data. If the expression does not evaluate to JSON data, an error is reported.

  • path_literal: the string that specifies the JSON path. If you set the parameter to a value of other types or an invalid path, an error is reported.

  • column_list: the list of column definitions. The expression must include at least one column definition; otherwise, an error is reported.

  • column: the specific column definition. The following types of columns are supported:

    • column_name FOR ORDINALITYFOR: provides an ID for a row. column_name is a column of the INT type.

    • column_name data_type PATH path_literal [json_value_on_empty_clause] [json_value_on_error_clause]: extracts values from path_literal as JSON data and then force converts it to the column type. A missing value triggers the optional clause json_value_on_empty_clause.

    • column_name data_type EXISTS PATH path_literal: returns 1 if any data exists in the path specified by path_literal, and 0 otherwise.

    • NESTED [PATH] path_literal COLUMNS (column_list): indicates a nested structure where column of any of the four types can be further defined.

  • data_type: the data type. The MySQL mode of OceanBase Database supports all data types except ENUM and SET.

  • alias: the table alias.

  • json_value_on_empty_clause: the expected behavior performed when the data filtered by the path is empty, which may be NULL, ERROR, or DEFAULT.

    • NULL ON EMPTY: sets the column to NULL, which is the default behavior.
    • DEFAULT json_string: parses json_string as the default value to replace the missing JSON object or array. OceanBase Database allows you to use a constant of any type as the default value.
    • ERROR ON EMPTY: throws an error.
  • json_value_on_error_clause: the expected behavior performed to override an error that occurs during expression evaluation, which may be NULL, ERROR, or DEFAULT. The options are the same as those of json_value_on_empty_clause.

    The following scenarios trigger the optional clause json_value_on_error_clause:

    • expr does not evaluate to properly formatted JSON data.

    • The JSON path expression points to a non-scalar value.

    • The JSON path expression points to no data.

    • The length of the data type specified for the return value is not large enough to hold the value.

Examples

Parse user input data

The following example parses the JSON data entered by a user and returns it as a relational table.

SELECT * FROM
  JSON_TABLE(
    '[{"x":"3"},{"a":2},{"b":1},{"a":0},{"a":[1,2]}]',
    '$[*]' COLUMNS (id FOR ORDINALITY,
             jpath VARCHAR(100) PATH '$.a'
                DEFAULT '33' ON EMPTY
                DEFAULT '66' ON ERROR,
             jsn_path JSON PATH '$.a' DEFAULT '{"x":33}' ON EMPTY,
             jexst INT EXISTS PATH '$.b')
  ) AS tt;

The query result is as follows:

+------+-------+-----------+-------+
| id   | jpath | jsn_path  | jexst |
+------+-------+-----------+-------+
|    1 | 33    | {"x": 33} |     0 |
|    2 | 2     | 2         |     0 |
|    3 | 33    | {"x": 33} |     1 |
|    4 | 0     | 0         |     0 |
|    5 | 66    | [1, 2]    |     0 |
+------+-------+-----------+-------+
5 rows in set

Extract data from a table

The following example extracts JSON data from a table and returns it as a relational table.

DROP TABLE IF EXISTS t1;

CREATE TABLE t1 (id INT, jd JSON);

INSERT INTO t1 VALUES (1, '[1,3,5]'),(2,'[2,4,6]');

SELECT id, jt.* FROM t1,
  JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
                                 val INT PATH '$')) AS jt;

SELECT /*+ JOIN_ORDER(jt, t1) */ id, jt.*
  FROM t1,
  JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
                                 val INT PATH '$')) AS jt;

The query result is as follows:

+------+------+------+
| id   | jid  | val  |
+------+------+------+
|    1 |    1 |    1 |
|    1 |    2 |    3 |
|    1 |    3 |    5 |
|    2 |    1 |    2 |
|    2 |    2 |    4 |
|    2 |    3 |    6 |
+------+------+------+
6 rows in set

Create a view

The following example generates a view based on the values returned by the JSON_TABLE() function.

CREATE VIEW v1 AS
  SELECT * FROM JSON_TABLE('[{"a": 1, "b": 2}]',
                           '$[*]' COLUMNS ( a INT PATH '$.b')) AS jt;

SELECT * FROM v1;

The query result is as follows:

+------+
| a    |
+------+
|    2 |
+------+
1 row in set

Check the view definition.

SHOW CREATE VIEW v1;

DROP VIEW v1;

The query result is as follows:

+------+-----------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View | Create View                                                                                                                       | character_set_client | collation_connection |
+------+-----------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| v1   | CREATE VIEW `v1` AS select `jt`.`a` AS `a` from JSON_TABLE('[{\"a\": 1, \"b\": 2}]' , '$[*]' columns (a INTEGER  path '$.b' )) jt | utf8mb4              | utf8mb4_general_ci   |
+------+-----------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
1 row in set

Insert data into a table

The following example inserts the values returned by the JSON_TABLE() function into a table.

DROP TABLE IF EXISTS t2;

CREATE TABLE t2 (id INT, a TINYINT, b VARCHAR(5), c DATE, d DECIMAL);

INSERT INTO t2 SELECT * FROM
  JSON_TABLE(JSON_ARRAY(JSON_OBJECT('a', 1, 'b', 'abc'),
                        JSON_OBJECT('a', 2, 'b', 'abcd'),
                        JSON_OBJECT('a', 1000, 'b', 'xyz'),
                        JSON_OBJECT('c', TIME'12:00:00', 'd', 1e308)),
             '$[*]' COLUMNS (id FOR ORDINALITY,
                             a TINYINT PATH '$.a' DEFAULT '111' ON ERROR,
                             b VARCHAR(5) PATH '$.b' DEFAULT '"ERR"' ON ERROR,
                             c DATE PATH '$.c' DEFAULT '"2001-01-01"' ON ERROR,
                             d DECIMAL PATH '$.c' DEFAULT '999' ON ERROR)
            ) AS jt;

SELECT * FROM t2 ORDER BY id;
DROP TABLE t2;

The query result is as follows:

+------+------+------+------------+-------+
| id   | a    | b    | c          | d     |
+------+------+------+------------+-------+
|    1 |    1 | abc  | NULL       |  NULL |
|    2 |    2 | abcd | NULL       |  NULL |
|    3 |  111 | xyz  | NULL       |  NULL |
|    4 | NULL | NULL | 2001-01-01 | 43200 |
+------+------+------+------------+-------+
4 rows in set

References

JSON data type

Contact Us