How to remove a number from MySQL's JSON array? - mysql

If I have a MySQL table with a JSON column called numbers and a record that has [1, 2, 3] in that column (array of integers), how do I update that record to remove the 2 (so it becomes [1, 3])?

I was searching for an answer my self and came to this question, not wanting to use objects I continued the search. But I found a solution, you need to use a combination of json_remove and json_search
The following removes the value 1 from the table tbl and the column numbers
UPDATE tbl
SET numbers = JSON_REMOVE(
numbers, replace(json_search(numbers, 'one', 1), '"', '')
)
WHERE json_search(numbers, 'one', 1) IS NOT NULL
json_search returns the path of where the value is, ie. "$[0]"
replace remove the " otherwise an error will occur with json_remove
json_remove will remove the path from the json_search result
Et voila, your value is removed.
Note: this assumes no duplicate values

Until someone finds a better solution, I just converted it to an object instead: {"1": 1, "2": 2, "3": 3}. Yes, this is uglier and occupies more disk space, but you get the benefit of not having to worry about duplicates.
To add a number:
update tbl set numbers = json_insert(`numbers`, '$."4"', 4);
To remove a number:
update tbl set numbers = json_remove(`numbers`, '$."4"');
To get the row with a certain number:
select * from tbl where json_contains_path(`numbers`, 'one', '$."4"');

By the way,
JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path]
...])
https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-search
just search_str

Related

replace a character in mysql with a random character from a list

i would like to perform Mysql search & replace with random characters, taken from a list. I cannot use regex, since my version is way prior to 8.
instead of the below,
i would like to change for instance the letter u with one out of (a,e,i,f,k) randomly.
UPDATE products
SET
productDescription = REPLACE(productDescription,
'abuot',
'about');
Is there a mysql command for this task?
Actually my goal is to get in the lastnames column, new names that are not exactly like the real ones, so one could work on "anonymous" data.
I would like to replace all rows in a certain column. Say in table products, in column description, we have data like:
abcud
ieruie
kjuklkllu
uiervfd
With the replace function, we would not want to create something like: replace e with i,
but replace e with one of (a,e,i,f,k)
example desired output:
abced
ierfie
kjiklkllk
aiervfd
like i said, we plan to use this into last names, we plan to replace many characters with random ones from a list, in an effort to create anonymous data in the column that contains last names.
On a next step, i would like to do the same, in order to make anonymous telephone numbers.
example
726456273
827364878
347823472
replace 3 with one of 0-9,
output:
726456279
827664878
547821472
SELECT REPLACE('product abuot Description',
SUBSTRING('product abuot Description', CHARINDEX('abuot', 'product abuot Description') ,5) , 'about')
CREATE FUNCTION smart_replace ( argument TEXT,
search_for CHAR(1),
replace_with TEXT )
RETURNS TEXT
NO SQL
BEGIN
SET argument = REPLACE(argument, search_for, CHAR(0));
REPEAT
SET argument = CONCAT( SUBSTRING_INDEX(argument, CHAR(0), 1),
SUBSTRING(replace_with FROM CEIL(RAND() * LENGTH(replace_with)) FOR 1),
SUBSTRING(argument FROM 2 + LENGTH(SUBSTRING_INDEX(argument, CHAR(0), 1))));
UNTIL NOT LOCATE(CHAR(0), argument) END REPEAT;
RETURN argument;
END
replace e with one of (a,e,i,f,k)
SELECT smart_replace(table.column, 'e', 'aeifk')
replace 3 with one of 0-9
SELECT smart_replace(table.phone, 'e', '0123456789')

How do I use JSON_SEARCH() to find the path of a number in a MySQL JSON array?

Note: This is for MySQL 5.7.
When I attempt to use JSON_SEARCH to find the path to a number value within a JSON array, I get NULL. But when I use JSON_SEARCH to look for a string, I actually get the path.
# String Search Example
SET #json = '[1, 2, 3, "abc"]';
SELECT JSON_SEARCH(#json, 'one', 'abc');
----------
| "$[3]" |
----------
...but when I explicitly search for a number value, I get NULL?
# Number Search Example
SET #json = '[1, 2, 3, "abc"]';
SELECT JSON_SEARCH(#json, 'one', 1);
----------
| NULL |
----------
What's strange is that JSON_CONTAINS still works as intended with numbers or strings.
This may be similar to this question -> MYSQL Triggers: JSON_SEARCH an integer value in a json array of integers
JSON_SEARCH function works with only string scalars as mentioned in the documentation : Functions That Search JSON Values
Here you can see:
Reported bug - JSON_SEARCH does not search for non-string values
Reported feature - Make JSON_SEARCH work for non-strings

Mysql regular expression or function for extracting numbers from a specific string

I have a column that has values of the forms:
AB232/10D20
A232/10D20
232/10D20
How can I extract the three numbers in mysql? I want to get 232, 10 and 20 separately and insert them in other columns.
For example, if the the column containing those values is called original_column, the query I need is something like this:
update mytable
set number_one = something(original_column),
number_two = something2(original_column),
number_three = something3(original_column)
Try the following query using LOCATE and SUBSTRING functions:
UPDATE mytable
SET number_one = SUBSTRING(original_column, LOCATE('/', original_column) - 3, 3),
number_two = SUBSTRING(original_column, LOCATE('/', original_column) + 1, 2),
number_three = SUBSTRING(original_column, -2, 2)
The middle number is easy. The last number and the first number are pretty easy, if we assume that they are always 3 and 2 characters.
update mytable
set number_one = right(substring_index(original_column, '/', 1), 3),
number_two = substring_index(original_column, '/', -1) + 0,
number_three = right(original_column, 2);
There are other tricks you can use if the columns are not exactly those lengths. But in your example, all the values have the same length.
When splitting it using regex, use the group feature. Regex for splitting 3 numbers with non-numeric delimiters (for integers only) would be
([0-9])[^0-9]([0-9])[^0-9]([0-9]*)
Use a regex tester to improve the regex.

MySQL - is it possible to update only part of value from current column?

Here is an example table on which I would like to execute a query:
Structure of table_1
number | photos (CHAR,4)
1234 | 1210
I would like to update value from column photos, but without changing the whole value. I would like change, for example, only third character to "2" without knowing the whole value. How can I do that?
I know I could do that in this way described below, but the problem is the value may be variable and it is a column type CHAR, not INT.
UPDATE table_1 SET photos = (photos + 10) where number='1234'
Yes with mid, left and right functions because photos is a type char:
UPDATE table_1 SET photos =
concat(
left( photos, 2),
'1',
right( photos, 1)
)
where number='1234'
Use concat(), left() and substring()
The example above would look like this:
update table_1
set photos = concat(left(photos, 2), "2", substring(photos, 4))
where number = '1234'
The advantage to this over left/right, is this will work for variable lengths of "photos".
Looking at it more generally, if you want to set the xth position to "2":
update table_1
set photos = concat(left(photos, x-1), "2", substring(photos, x+1))
where number = '1234'
(NOTE: I don't have MySQL running right now so I can't test the above. There are certain to be off-by-one errors which should be easy for your to correct)
If the column contains only numbers then the example you gave would work. The value will be converted to an integer, added to, and then converted back.
You might want to explain your reasoning for wanting to do this though. It seems a bit strange.

How to separate value by using comma my SQL?

My table column has rows like this 1001, 1002, 1003 and so on separated by commas. There may be 1 or more comma separated values in each column. I need the total count of these comma separated values in the table. For example if my table has 2 rows one having 1001, 1002, 1003, 1004 and another with 1001, 1005 the output i should get is 6 i.e. 4+2. Kindly assist
there is no function in mysql to count char occurences. but you can replace every comma with nothing. and then you calculate the difference of lenghts which will give you the number of commas, which is one less than the number of values.
select
( LENGTH(col1) - LENGTH(REPLACE(col1, ',', '')) + 1 )
+ ( LENGTH(col2) - LENGTH(REPLACE(col2, ',', '')) + 1 )
AS valCount
from T;
(didn't test that explicitely but at least something very similar to that will do the job.)
replace()
length()
Try:
SELECT SUM(LEN(ColumnName) - LEN(REPLACE(ColumnName, ',', ''))) FROM TableName
This is one of those tasks that'd be much, much easier in the server-side script accessing your database than the database itself. Assuming you've already assigned the comma-separated strings to an array (where $array[1] is equal to the string from row 1:
$array = array("1001, 1002, 1003, 1004", "1001, 1005"); // assigned from database
foreach($array as $k => $v){
$numbersInString[$k] = count(explode(', ', $v));
}
echo implode(' + ',$numbersInString);
This is possible, with creative solutions (such as that from Raffael1984), in MySQL, but seems to much more easily, and concisely, implemented in PHP.
References:
count().
explode().
implode().
foreach().
Did you try using the count() function? You can specify which rows if you need to.
.row[COUNT(name)]
in your query. What does your table look like? I might be able to help more if I know what it looks like