Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a MySQL 5.7 JSON NULL to native MySQL NULL?

This code:

SELECT JSON_EXTRACT('{"hello": null}', '$.hello')

Returns null.

However, this is not the MySQL native NULL. For example, this:

SELECT COALESCE(JSON_EXTRACT('{"hello": null}', '$.hello'), 'world')

also yields null.

How do I convert this JSON null to MySQL native NULL?

I suppose that I could use IF with some comparisons but it doesn't seem like the proper way to do it...

like image 290
obe Avatar asked Jun 13 '16 17:06

obe


People also ask

Does MySQL 5.7 support JSON?

JSON support was introduced in MySQL 5.7. 8. In addition to the benefits just listed, having JSON as a native type in MySQL means that the database can automatically validate JSON documents stored in JSON columns.

Does MySQL 5.6 support JSON?

- Supports all the JSON types – Numbers , string, Bool , objects & arrays.

Does MySQL support Jsonb?

MySQL supports a native JSON data type defined by RFC 7159 that enables efficient access to data in JSON (JavaScript Object Notation) documents. The JSON data type provides these advantages over storing JSON-format strings in a string column: Automatic validation of JSON documents stored in JSON columns.

IS NULL equivalent in MySQL?

In MySQL, a NULL value means unknown. A NULL value is different from zero ( 0 ) or an empty string '' . A NULL value is not equal to anything, even itself. If you compare a NULL value with another NULL value or any other value, the result is NULL because the value of each NULL value is unknown.


Video Answer


4 Answers

Unfortunately CAST('{}' AS JSON) will not work is this case, but NULLIF works:

  1. Full methods:

    SELECT NULLIF(JSON_UNQUOTE(JSON_EXTRACT('{"hello": null}', '$.hello')), 'null') IS NULL;

  2. Shorted:

    SELECT NULLIF(helloColumn ->> '$.hello', 'null') IS NULL IS NULL;

like image 106
sergolius Avatar answered Oct 16 '22 08:10

sergolius


This question is about MySQL 5.7, but I would like to add the solution for MySQL 8.0.

With MySQL 8.0.21 we have now the possibility to use the JSON_VALUE function (part of SQL Standard) to extract and optionally convert the value to a (MySQL) type.

mysql> SET @doc = '{"a": null}';

mysql> SELECT JSON_VALUE(@doc, '$.a' RETURNING SIGNED);
+------------------------------------------+
| JSON_VALUE(@doc, '$.a' RETURNING SIGNED) |
+------------------------------------------+
|                                     NULL |
+------------------------------------------+

mysql> SET @doc = '{"a": 2}';

mysql> SELECT JSON_VALUE(@doc, '$.a' RETURNING SIGNED);
+------------------------------------------+
| JSON_VALUE(@doc, '$.a' RETURNING SIGNED) |
+------------------------------------------+
|                                        2 |
+------------------------------------------+
like image 37
geertjanvdk Avatar answered Oct 16 '22 08:10

geertjanvdk


Assume you have a table called 'mytable' that contains a json column called 'data'. I usually have to use a construct like this:

SELECT 
  CASE WHEN data->>'$.myfield' = 'null' THEN NULL ELSE data->>'$.myfield' END myfield
FROM mytable

Or create a virtual field as follows:

ALTER TABLE mytable ADD myfield VARCHAR(200) GENERATED ALWAYS AS (
  CASE WHEN data->>'$.myfield' = 'null' THEN NULL ELSE data->>'$.myfield' END
) VIRTUAL;
like image 1
David Carr Avatar answered Oct 16 '22 08:10

David Carr


Looks official discussion is under progress but not much active.

Here is one more jury rigging:

mysql> SELECT CAST('null' AS JSON), JSON_TYPE(CAST('null' AS JSON)) = 'NULL';
+----------------------+------------------------------------------+
| CAST('null' AS JSON) | JSON_TYPE(CAST('null' AS JSON)) = 'NULL' |
+----------------------+------------------------------------------+
| null                 |                                        1 |
+----------------------+------------------------------------------+
1 row in set (0.00 sec)

mysql> select @@version;
+---------------+
| @@version     |
+---------------+
| 5.7.21-20-log |
+---------------+
1 row in set (0.00 sec)
like image 1
dgregory Avatar answered Oct 16 '22 09:10

dgregory