Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't detect null value from JSON_EXTRACT

Tags:

mysql

I have a database that has an array of data stored in a JSON column. I need to find all values that have a null value at a particular position in the JSON array. While pulling out the data with JSON_EXTRACT seemed trivial, none of my comparisons to null have worked, all of them claiming the value is null.

Here is the example code that should work as far as I can tell:

SELECT JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]') , (JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]') is null)
FROM ate.readings_columns_new;

The first few rows of my results table look like this:

null                    |   0
"INTERNALTEMPERATURE"   |   0
"INPUT_VOLTAGE"         |   0
null                    |   0
null                    |   0
"AH1"                   |   0

I have tried every comparison I can think of, and they all result in a 0:

(JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]') is null)
(JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]') <=> null)
ISNULL(JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]'))
(JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]') <=> 'null')

Is there some key to comparing null values pulled from a JSON_EXTRACT?

like image 239
Fr33dan Avatar asked Dec 15 '16 19:12

Fr33dan


People also ask

How do I check if a JSON is null?

To check null in JavaScript, use triple equals operator(===) or Object is() method. If you want to use Object.is() method then you two arguments. 1) Pass your variable value with a null value. 2) The null value itself.

Can JSON include Null?

JSON has a special value called null which can be set on any type of data including arrays, objects, number and boolean types.

What is JSON extract () function in MySQL?

We can use the JSON_EXTRACT function to extract data from a JSON field. The basic syntax is: JSON_EXTRACT(json_doc, path) For a JSON array, the path is specified with $[index] , where the index starts from 0: mysql> SELECT JSON_EXTRACT('[10, 20, 30, 40]', '$[0]'); +------------------------------------------+


2 Answers

SELECT 
  JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]'), 
  (JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]') = CAST('null' AS JSON))
FROM ate.readings_columns_new;

or

SELECT 
  JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]'), 
  (JSON_TYPE(JSON_EXTRACT(`COLUMNS_HEADERS`, '$[1]')) = 'NULL')
FROM ate.readings_columns_new;

See the docs for JSON_TYPE.

like image 176
abl Avatar answered Sep 20 '22 16:09

abl


A bit of a belated answer but I just hit this problem and couldn't find anything reasonably documented. The solution I ended ended up using was the json_type function as 'abl' pointed out above.

The trick was to compare with the string 'NULL' not null or NULL.

As a test throw the following into a mysql prompt and play around with the values

(if using phpMyAdmin don't forget to check 'show this query here again' and 'retain query box' - the universe is frustrating enough without losing edits..)

set @a='{"a":3,"b":null}';

select if(json_type(json_extract(@a,'$.b')) = 'NULL',1,0);

I ended up with the following.

mysql> set @a='{"a":3,"b":null}';
Query OK, 0 rows affected (0.00 sec)

mysql> select if(json_type(json_extract(@a,'$.b')) = 'NULL',1,0);
+----------------------------------------------------+
| if(json_type(json_extract(@a,'$.b')) = 'NULL',1,0) |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+
1 row in set (0.00 sec)

mysql> set @a='{"a":3,"b":1}';
Query OK, 0 rows affected (0.00 sec)

mysql> select if(json_type(json_extract(@a,'$.b')) = 'NULL',1,0);
+----------------------------------------------------+
| if(json_type(json_extract(@a,'$.b')) = 'NULL',1,0) |
+----------------------------------------------------+
|                                                  0 |
+----------------------------------------------------+
1 row in set (0.00 sec)

As the bare bones of a stored procedure - which is what I needed it for - using the 'if' statements rather than the if() function.

drop procedure if exists test;
delimiter $$

create procedure test(in x json)
begin

if json_type(json_extract(x,'$.b')) = 'NULL' then
  select 1;
else 
  select 0;
end if;

end$$

delimiter;

mysql> call test('{"a":3,"b":1}');
+---+
| 0 |
+---+
| 0 |
+---+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> call test('{"a":3,"b":null}');
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
like image 30
Brenton Thomas Avatar answered Sep 19 '22 16:09

Brenton Thomas