MySQL version = 5.7.29
I want to do a MySQL search on a column which has delimited data. For example:
'field_black:1, field_white:2, field1_black:5, field_green:3'
I want a function which takes input the color and returns only the delimited values which do not have the input color.
func(input, color, delimiter)
func('field_black:1, field_white:2, field1_black:5, field1_green:3', 'black', ',') = 'field_white:2, field1_green:3'
This is pretty easy to implement in python using string split on delimiter and returning result set where the color is not in the given input.
def func(inp, col, delim):
inp = inp.split(delim)
res = []
for data in inp:
if col not in data:
res.append(data)
return (','.join(res))
Can anyone help me with an equivalent implementation in MySQL.
Thank you for the help!
CREATE FUNCTION func (input TEXT, color TEXT, delimiter CHAR(1))
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE piece TEXT;
DECLARE result TEXT DEFAULT '';
/* SET color = CONCAT('field_', color); */ /* uncomment if needed */
REPEAT
SET piece = SUBSTRING_INDEX(input, delimiter, 1);
SET input = SUBSTRING(input FROM 2 + LENGTH(piece) FOR LENGTH(input));
IF NOT LOCATE(color, piece) THEN
SET result = CONCAT(result, delimiter, TRIM(piece));
END IF;
UNTIL input = ''
END REPEAT;
RETURN TRIM(BOTH delimiter FROM result);
END
fiddle
PS. Of course you may use multi-char delimiter if needed - alter input parameter type simply.
Just cracked this after a few iterations due to unfamiliarity with MySQL syntax. This is unnecessarily complicated though.
Answer by Akina is more simple and elegant: mysql delimit and search column data
CREATE FUNCTION `new_function`(input longtext, col TEXT, delim CHAR(1)) RETURNS longtext CHARSET utf8
DETERMINISTIC
BEGIN
declare result longtext default '';
declare piece longtext default '';
declare inptext longtext default '';
set inptext = input;
while (substring_index(inptext,delim,1) = '') = 0 DO
set piece = substring_index(inptext,delim,1);
IF NOT LOCATE(col, piece) THEN
set result = concat(result, piece, delim);
END IF;
set inptext = substr(inptext, length(SUBSTRING_INDEX(inptext, '|', 1) ) + 2);
END WHILE;
set result = left(result, length(result) -1);
RETURN result;
END
Related
I want replace random word in WordPress post. I have a code for MySQL.
This code working well:
update wp_posts set post_content =
replace(post_content,'oldword','newword');
But when I want replace random in database like
replace(post_content,'oldword',rand('newword','google','stackoverflow','stackover'));
This code not working.
I don't know how use this code for random replace word.
I want each occurrence of oldword to be replaced by a different word
Error
SQL query:
UPDATE wp_posts SET post_content =
REPLACE_RANDOM(post_content, 'oldword')
MySQL said: Documentation
#1366 - Incorrect string value: '\xD8\xA7\xDB\x8C\xD9\x86...' for column 'String' at row 1
Where is the problem?
DELIMITER $$
DROP FUNCTION IF EXISTS Replace_Random$$
CREATE FUNCTION Replace_Random(String TEXT, Word TEXT)
RETURNS TEXT
BEGIN
DECLARE New TEXT DEFAULT '';
DECLARE Loc INT DEFAULT INSTR(String, Word);
DECLARE WLen INT DEFAULT Length(Word);
WHILE Loc DO
SET New = CONCAT(New, SUBSTR(String, 1, Loc-1), ELT(FLOOR(RAND()*5)+1, 'biterrr', 'stackoverflow', 'serress', 'ms-ms-ms', 'Nick'));
SET String = SUBSTR(String, Loc + WLen);
SET Loc = INSTR(String, Word);
END WHILE;
SET NEW = CONCAT(New, String);
RETURN New;
END$$
DELIMITER ;
UPDATE wp_posts SET post_content =
REPLACE_RANDOM(post_content, 'oldword');`
You could use ELT to pick a random value from a list of strings:
UPDATE wp_posts SET post_content =
REPLACE(post_content, 'oldword', ELT(FLOOR(RAND()*5)+1, 'hello', 'world', 'friend', 'tuesday', 'sunny'))
If you have a different number of strings in the list, just change the multiplier of RAND() from 5 to the number of strings.
Update
If you need to replace multiple occurrences of the string in a phrase with different words, you will need a stored function. This one will do the job:
DELIMITER \\
DROP FUNCTION IF EXISTS Replace_Random\\
CREATE FUNCTION Replace_Random(String TEXT CHARACTER SET utf8, Word TEXT CHARACTER SET utf8)
RETURNS TEXT CHARACTER SET utf8
BEGIN
DECLARE New TEXT CHARACTER SET utf8 DEFAULT '';
DECLARE Loc INT DEFAULT INSTR(String, Word);
DECLARE WLen INT DEFAULT Length(Word);
WHILE Loc DO
SET New = CONCAT(New, SUBSTR(String, 1, Loc-1), ELT(FLOOR(RAND()*5)+1, 'hello', 'world', 'friend', 'tuesday', 'sunny'));
SET String = SUBSTR(String, Loc + WLen);
SET Loc = INSTR(String, Word);
END WHILE;
SET NEW = CONCAT(New, String);
RETURN New;
END\\
DELIMITER ;
SELECT REPLACE_RANDOM('a string with oldword in it twice - oldword!', 'oldword');
Output (varies):
a string with sunny in it twice - tuesday!
a string with hello in it twice - friend!
I need to sort below cell values using mysql
Example:
cell contain red,blue,green
But I want that in alphabetic order.
Steps to do this,
1.First you need to make a procedure call for sorting values
2.Call your procedure then
Here is the code to create mysql procedure
-- sort comma separated substrings with unoptimized bubble sort
DROP FUNCTION IF EXISTS sortString;
DELIMITER |
CREATE FUNCTION sortString(inString TEXT) RETURNS TEXT
BEGIN
DECLARE delim CHAR(1) DEFAULT ','; -- delimiter
DECLARE strings INT DEFAULT 0; -- number of substrings
DECLARE forward INT DEFAULT 1; -- index for traverse forward thru substrings
DECLARE backward INT; -- index for traverse backward thru substrings, position in calc. substrings
DECLARE remain TEXT; -- work area for calc. no of substrings
-- swap areas TEXT for string compare, INT for numeric compare
DECLARE swap1 TEXT; -- left substring to swap
DECLARE swap2 TEXT; -- right substring to swap
SET remain = inString;
SET backward = LOCATE(delim, remain);
WHILE backward != 0 DO
SET strings = strings + 1;
SET backward = LOCATE(delim, remain);
SET remain = SUBSTRING(remain, backward+1);
END WHILE;
IF strings < 2 THEN RETURN inString; END IF;
REPEAT
SET backward = strings;
REPEAT
SET swap1 = SUBSTRING_INDEX(SUBSTRING_INDEX(inString,delim,backward-1),delim,-1);
SET swap2 = SUBSTRING_INDEX(SUBSTRING_INDEX(inString,delim,backward),delim,-1);
IF swap1 > swap2 THEN
SET inString = TRIM(BOTH delim FROM CONCAT_WS(delim
,SUBSTRING_INDEX(inString,delim,backward-2)
,swap2,swap1
,SUBSTRING_INDEX(inString,delim,(backward-strings))));
END IF;
SET backward = backward - 1;
UNTIL backward < 2 END REPEAT;
SET forward = forward +1;
UNTIL forward + 1 > strings
END REPEAT;
RETURN inString;
END |
DELIMITER ;
To make procedure call just you have to use,
-- example call:
SET #Xstr = "red,blue,green"; // for query purpose only you need to write within (SQL Query here for that row)
SELECT sortString(#Xstr) AS s1
Please see the documentation guide map
Click here to read
Also there is an alternative way to do if you are interested to study is that about FIND_IN_SET, please you can find some idea from one of the question from stackoverflow. Click here to read
You can create a function which sorts the items in the column:
create function f_comma_list_order ( t text )
returns text
begin
declare v_c int;
drop temporary table if exists tmp;
create temporary table tmp ( v text );
set v_c = 1;
while( v_c > 0 ) do
select locate(',', t) into v_c;
if (v_c>0) then
insert into tmp select substr(t, 1, v_c-1);
set t = substr(t, v_c+1);
else
insert into tmp values (t);
end if;
end while;
select group_concat(v order by v) into t
from tmp;
return t;
end
and then call the function:
select f_comma_list_order('red,green,blue')
I am trying to run a query that can find all the records from a field contains the letters.
For example suppose a state field contains a record value "New York" and another record conatains NY. Now i am searching for NY or New york will return these 2 records. What will be the query.
Currently i am using
like %New York%" or "%NY%"
Any suggestion
No your query is not correct as it searches for anything containing New York or NY.
So if there is PENNY that will be matched although it shouldn't be....
Your query must be something like this.
SELECT * from TABLE where field in ('NEW YORK','NY')
Now to fetch acronym,you can use
delimiter $$
drop function if exists `initials`$$
CREATE FUNCTION `initials`(str text, expr text) RETURNS text CHARSET utf8
begin
declare result text default '';
declare buffer text default '';
declare i int default 1;
if(str is null) then
return null;
end if;
set buffer = trim(str);
while i <= length(buffer) do
if substr(buffer, i, 1) regexp expr then
set result = concat( result, substr( buffer, i, 1 ));
set i = i + 1;
while i <= length( buffer ) and substr(buffer, i, 1) regexp expr do
set i = i + 1;
end while;
while i <= length( buffer ) and substr(buffer, i, 1) not regexp expr do
set i = i + 1;
end while;
else
set i = i + 1;
end if;
end while;
return result;
end$$
drop function if exists `acronym`$$
CREATE FUNCTION `acronym`(str text) RETURNS text CHARSET utf8
begin
declare result text default '';
set result = initials( str, '[[:alnum:]]' );
return result;
end$$
delimiter ;
So,your final query will be something like this.
SELECT * from TABLE where field in ('NEW YORK',select acronym('Come Again? That Cant Help!'))
Source:- Mysql extract first letter of each word in a specific column
Presumably, the logic that you want is:
col like '%New York%' or col like '%NY%'
or, if you want to use regular expressions:
col regexp 'New York|NY'
Select * from table where col like '%N' or col like '%n'
I'm trying to get a random string in phpmyadmin using a function.
I have the following code:
CREATE FUNCTION randomPassword()
RETURNS varchar(128)
BEGIN
SET #chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
SET #charLen = length(#chars);
SET #randomPassword = '';
WHILE length(#randomPassword) < 12
SET #randomPassword = concat(#randomPassword, substring(#chars,CEILING(RAND() * #charLen),1));
END WHILE;
RETURN #randomPassword ;
END;
Now I get the error:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5
Does anyone know how I can fix this?
This is faster than concat + substring routine.
select substring(MD5(RAND()),1,20);
As I've tested inserting 1M random data, md5 routine consumes only 1/4 (even less) time of concat + substring routine;
The problem is a md5 string contains only 32 chars so if you need a longer one you'd have to manually generate more md5 strings and substring it yourself.
Try this more simple solution:
SELECT CONV(FLOOR(RAND() * 99999999999999), 10, 36)
SELECT SUBSTRING(REPLACE(REPLACE(REPLACE( TO_BASE64(MD5(RAND())), '=',''),'+',''),'/',''), 2, 40)
This solution to generate a fixed length random string that contains all lower- and upper-case chars and digits.
SELECT SUBSTRING(REPLACE(REPLACE(REPLACE( TO_BASE64(MD5(RAND())), '=',''),'+',''),'/',''), 2, FLOOR(10+RAND()*31))
If you need a random length string (from 10 to 40 symbols in this example)
It's solved by using the Delimiter, i don't know for sure how, but it works
Thanks
DELIMITER $$
CREATE FUNCTION randomPassword()
RETURNS varchar(128)
BEGIN
SET #chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
SET #charLen = length(#chars);
SET #randomPassword = '';
WHILE length(#randomPassword) < 12
DO
SET #randomPassword = concat(#randomPassword, substring(#chars,CEILING(RAND() * #charLen),1));
END WHILE;
RETURN #randomPassword ;
END$$
DELIMITER ;
CREATE FUNCTION randomPassword()
RETURNS varchar(128)
AS
BEGIN
declare #chars nvarchar(25);
declare #charlen int;
declare #randomPassword nvarchar(128);
SET #chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
SET #charLen = len(#chars);
SET #randomPassword = '';
WHILE(LEN(#randomPassword) < 12)
BEGIN
SET #randomPassword = concat(#randomPassword, substring(#chars,CEILING(RAND() * #charLen),1));
END
RETURN #randomPassword
END
I have a set of characters that are defined as valid characters. Let me define the valid string by the following regexp:
^[a-zA-Z0-9\ .-_]+$
(alphanumeric, space, dot, dash and underscore)
The question is that given a column containing a lot of invalid characters, how I can run an update to convert each invalid character to one space? And then possibly convert consequent spaces to one space?
I cannot run several replace commands because there are a lot of possible invalid characters. So I expect a regexp solution.
Currently, I am doing the task in Java (after exporting the table to tsv format). But I want a MySQL approach.
If your MySQL version supports it, create a function:
DELIMITER $$
CREATE FUNCTION my_func_1 (str TEXT)
RETURNS TEXT
BEGIN
DECLARE ret TEXT DEFAULT '';
DECLARE chr TEXT DEFAULT '';
DECLARE i INT DEFAULT 1;
WHILE i < (LENGTH(str) + 1) DO
SET chr = SUBSTRING(str, i, 1);
IF chr REGEXP '[-a-zA-Z0-9\\_.]'
THEN SET ret = CONCAT(ret, chr);
ELSE
SET ret = CONCAT(ret, ' ');
END IF;
SET i = i + 1;
END WHILE;
WHILE ret LIKE '% %' DO
SET ret = REPLACE(ret, ' ', ' ');
END WHILE;
RETURN TRIM(ret);
END;
$$
DELIMITER ;
Test it a bit:
SELECT my_func_1('$a-B\\?!=01._%'); > a-B\ 01._
and update with SET col = my_func_1(col)
If not needed anymore:
DROP FUNCTION IF EXISTS my_func_1;
Also I changed your regex a bit as - indicates a range, if between characters in a class or is .-_ intended? Then modify the pattern.