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...
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.
- Supports all the JSON types – Numbers , string, Bool , objects & arrays.
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.
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.
Unfortunately CAST('{}' AS JSON)
will not work is this case,
but NULLIF
works:
Full methods:
SELECT NULLIF(JSON_UNQUOTE(JSON_EXTRACT('{"hello": null}', '$.hello')), 'null') IS NULL;
Shorted:
SELECT NULLIF(helloColumn ->> '$.hello', 'null') IS NULL IS NULL;
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 |
+------------------------------------------+
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;
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With