Reputation: 1664
I have a JSON-typed column in a MySQl table. This column stores an array of integer values, like '[1,2,3]'.
What I want is: when I insert a new value into this array using JSON_ARRAY_INSERT/JSON_ARRAY_APPEND, if the value already exists, simply ignore it.
How can I do this within MySQL? That is, NOT checking duplicates from calling scripts like PHP or Node.js, etc.
Update: I'd prefer to use a built-in MySQL mechanism for this purpose, because if done in external scripts, there would be a small chance that duplicates happen due to race conditions, even if I check against duplicates before storing the data.
Thanks!
Upvotes: 2
Views: 4301
Reputation: 1
DECLARE lc,leng,du INT(50);
DECLARE conc,vb VARCHAR(50);
DECLARE new_array JSON;
SET new_array='[]';
SET lc=0;
SET leng=JSON_LENGTH(first_array);
WHILE lc<leng DO
SET conc=(SELECT CONCAT('$[',lc,']'));
IF JSON_CONTAINS(JSON_UNQUOTE(new_array),CONCAT('"',JSON_UNQUOTE(JSON_EXTRACT(first_array,conc)),'"')) THEN
SET du=1;
ELSE
SET new_array=(SELECT JSON_ARRAY_APPEND(new_array,'$',(JSON_UNQUOTE(JSON_EXTRACT(first_array,conc)))));
end if;
SET lc=lc+1;
END WHILE;
RETURN new_array;
This function returns non duplicate JSON array in MySQL
first array is a json_array
input parameter
Upvotes: 0
Reputation: 21
set @j='[1, 2, 3]';
set @v=1;
SELECT IF(JSON_CONTAINS(@j, CAST(@v AS JSON), '$') = 1, @j, json_array_append(@j, '$', CAST(@v AS JSON)));
OUTPUT:
[1, 2, 3]
set @j='[1, 2, 3]';
set @v=4;
SELECT IF(JSON_CONTAINS(@j, CAST(@v AS JSON), '$') = 1, @j, json_array_append(@j, '$', CAST(@v AS JSON)));
OUTPUT:
[1, 2, 3, 4]
Upvotes: 0
Reputation: 199
Hope this helps.
Schema (MySQL v5.7)
CREATE TABLE test (
id INT,
js JSON
);
INSERT INTO test (id, js) VALUES (1, '[1,2,3]');
INSERT INTO test (id, js) VALUES (2, '[1,2]');
Query #1
select * from test;
| id | js |
| --- | --------- |
| 1 | [1, 2, 3] |
| 2 | [1, 2] |
Query #2
UPDATE test
SET js = JSON_ARRAY_APPEND (js, '$', 3)
WHERE id = 1 and not JSON_CONTAINS(js, '3', '$');
UPDATE test
SET js = JSON_ARRAY_APPEND (js, '$', 3)
WHERE id = 2 and not JSON_CONTAINS(js, '3', '$');
Query #3
select * from test;
| id | js |
| --- | --------- |
| 1 | [1, 2, 3] |
| 2 | [1, 2, 3] |
Upvotes: 1
Reputation: 147146
Without knowing your exact table structure it's difficult to give a precise answer, but the following queries demonstrate how it's done with variables. You would just need to adapt this according to your columns.
set @j='["1","2","3"]';
set @v = "4";
select ifnull(json_search(@j, 'one', @v), @j:=json_array_append(@j, '$', @v));
set @v = "1";
select ifnull(json_search(@j, 'one', @v), @j:=json_array_append(@j, '$', @v));
select @j;
Output:
["1", "2", "3", "4"]
Upvotes: 3