Update data only if the letter is not in front - mysql

My Data:
TAn
Ants
TAr
Arm
TogA
UPDATE sample SET sample_data = REPLACE(sample_data , 'A', 'a');
The above shows my data and the SQL code i am using to change A to a. However i only want to change A to a on if A is not the first letter. How can i accomplish this in MySQL?

Only call REPLACE on SUBSTRING(sample_data, 2)
UPDATE sample
SET sample_data = CONCAT(LEFT(sample_data, 1), REPLACE(SUBSTRING(sample_data, 2), 'A', 'a'))

Related

Split a column into 2 columns mysql table

I have this column in mysql table:
LOT_LOCATION
SGBAKE.0013
SGHAST.0008Z1
SGHAST.0011ZU
How to split to this table[MANAGED TO DO SO BUT DK HOW TO CHANGE THE TABLE ITSELF):
LOT_LOCATION, Zone Attribute
SGBAKE.0013, ''
SGHAST.0008, Z1
SGHAST.0011, ZU
Any help is appreciated thanks!
my code only select 2 columns but does not alter the table and I dont know how to put condition in creation and alteration of columns:
select if(locate('Z',LOT_LOCATION)=0,LOT_LOCATION,substring_index(LOT_LOCATION, 'Z', 1)),
if(locate('Z',LOT_LOCATION)=0,'',substring_index(LOT_LOCATION, 'Z', -1))
As Zone_Attribute
from skynet_msa.Lab_WIP_History;
I tried this UPDATE but suddenly the zone attribute column values disappear
UPDATE Lab_WIP_History
SET LOT_LOCATION = if(locate('Z',LOT_LOCATION)=0,LOT_LOCATION,substring_index(LOT_LOCATION, 'Z', 1)),
`Zone Attribute` = if(locate('Z',LOT_LOCATION)=0,'',substring_index(LOT_LOCATION, 'Z', -1))
lot_location is updated before zone_attribute - ie the zone_attribute test finds no z in lot_location btw your select query does not produce the result you claim
reverse the order of the set statement
UPDATE Lab_WIP_History
SET `Zone Attribute` = if(locate('Z',LOT_LOCATION)=0,'',substring_index(LOT_LOCATION, 'Z', -1)),
LOT_LOCATION = if(locate('Z',LOT_LOCATION)=0,LOT_LOCATION,substring_index(LOT_LOCATION, 'Z', 1))
;

using a regex to remove invalid values from image

working on a code where we are storing images but some images ending with weird characters
like , %2C -x1 to x10 etc or more but always end wih a .jpg
how can i regex to replace the image name to be a valid name
here is an example of what i have
PCpaste_10_g,-X1,-X2,-X3
SNBar_NEW,-X1
they can go till -X10
so i want to have regex to remove ,and everything afterwards it
i tried using replace but that only works for one item at a time
If your data is consistent with the string before the first comma that need to be taken, then you can try with SUBSTRING_INDEX;
Let's use this as you sample table & using your sample data:
CREATE TABLE mytable (
val VARCHAR(255));
INSERT INTO mytable VALUES
('PCpaste_10_g,-X1,-X2,-X3.jpg'),
('SNBar_NEW,-X1.jpg');
val
PCpaste_10_g,-X1,-X2,-X3.jpg
SNBar_NEW,-X1.jpg
Then first you extract the first string before comma occurrence:
SELECT SUBSTRING_INDEX(val,',',1) extracted
FROM mytable
returns
extracted
PCpaste_10_g
SNBar_NEW
Then to add back .jpg:
SELECT CONCAT(SUBSTRING_INDEX(val,',',1),'.jpg') extracted_combined
FROM mytable
IF your image extension is not consistently .jpg, you can do another SUBSTRING_INDEX() to get the extension then CONCAT() them:
SELECT CONCAT(SUBSTRING_INDEX(val,',',1) ,'.',
SUBSTRING_INDEX(val,'.',-1)) Extracted_combined
FROM mytable;
Demo fiddle
You can use LOCATE to find the first occurrence of "," in the field and LEFT to grab everything up to the first "," -
SET #value := 'PCpaste_10_g,-X1,-X2,-X3';
SELECT CONCAT(LEFT(#value, LOCATE(',', #value) - 1), '.jpg');
or for your update -
UPDATE <table>
SET image_name = CONCAT(LEFT(image_name, LOCATE(',', image_name) - 1), '.jpg')
WHERE image_name LIKE '%,%';
or to handle your %2C at the same time -
UPDATE <table>
SET image_name = CASE
WHEN image_name LIKE '%,%'
THEN CONCAT(LEFT(image_name, LOCATE(',', image_name) - 1), '.jpg')
WHEN image_name LIKE '%\%2C%'
THEN CONCAT(LEFT(image_name, LOCATE('%2C', image_name) - 1), '.jpg')
END
WHERE image_name LIKE '%,%'
OR image_name LIKE '%\%2C%';

mysql replace a character with another

I have a table with some values like below,
Slno
---------
IFAAA1121
IFAAA1122
IMBBB1121
IMBBB11223
My goal is to reformat the SlNo in to the below format,
Slno
---------
IF-AAA-1121
IF-AAA-1122
IM-BBB-1121
IM-BBB-11223
How is it possible ?
My query is:
UPDATE `certificate_log_uae`
SET `DeviceSerialNumberTemp` = REPLACE(LEFT(DeviceSerialNumberTemp,2),
LEFT(DeviceSerialNumberTemp,2).'-')
You can use the Substr() function to get substrings out from your input string, at various positions and lengths.
Since the length of the last substring is not fixed; we can simply specify the start position to slice the substring, and leave specifying the length parameter. It will consider the substring till the end of the overall string.
Now, just concatenate this substrings back using - appropriately.
Try the following:
UPDATE `certificate_log_uae`
SET `DeviceSerialNumberTemp` = CONCAT(SUBSTR(`DeviceSerialNumberTemp`, 1, 2),
'-',
SUBSTR(`DeviceSerialNumberTemp`, 3, 3),
'-',
SUBSTR(`DeviceSerialNumberTemp`, 6)
)
One approach would be to just build the final string you want using concatenation:
UPDATE certificate_log_uae
SET DeviceSerialNumberTemp = CONCAT(LEFT(DeviceSerialNumberTemp, 2),
'-',
SUBSTRING(DeviceSerialNumberTemp, 3, 3),
'-',
SUBSTRING(DeviceSerialNumberTemp, 6));
Demo
If you are using MySQL 8+ or later, then there is a very simple regex based solution using REGEXP_REPLACE:
SELECT
DeviceSerialNumberTemp,
REGEXP_REPLACE(DeviceSerialNumberTemp, '(.{2})(.{3})(.*)', '$1-$2-$3') AS output
FROM certificate_log_uae;
Demo
Try simple insert function:
select Slno, insert(insert(slno, 3, 0, '-'), 7, 0, '-') from tbl
Demo
To update values try:
update certificate_log_uae set
DeviceSerialNumberTemp = insert(insert(DeviceSerialNumberTemp , 3, 0, '-'), 7, 0, '-')

MySQL: How do I search and replace chars at the beginning of a string

I'm trying to search and replace mobile numbers with the full international code.
So where rows have 07970000007 to replace the beginning with +447970000007
UPDATE tblMemberImportClub
SET msisdn = REPLACE(msisdn, '07', '+447')
WHERE INSTR(msisdn, '07') = 1;
But this also replaces the other matches:
+4479700000+447
I don't think i can use TRIM as some rows will already start with +447 and will therefore nor require any updates.
Thanks in advance for any assistance.
Use LIKE and INSERT():
UPDATE tblMemberImportClub
SET msisdn = INSERT(msisdn, 1, 2, '+447')
WHERE msisdn LIKE '07%';
INSERT() is a string function that replaces exactly the characters you specify (see here).
SELECT
CONCAT(
REPLACE(
LEFT('07970000007',2), '07', '+447'
),
SUBSTRING('07970000007', 3, CHAR_LENGTH('07970000007'))
)as replaced

SQL: search/replace but only the first time a value appears in record

I have html content in the post_content column.
I want to search and replace A with B but only the first time A appears in the record as it may appear more than once.
The below query would obviously replace all instances of A with B
UPDATE wp_posts SET post_content = REPLACE (post_content, 'A', 'B');
This should actually be what you want in MySQL:
UPDATE wp_post
SET post_content = CONCAT(REPLACE(LEFT(post_content, INSTR(post_content, 'A')), 'A', 'B'), SUBSTRING(post_content, INSTR(post_content, 'A') + 1));
It's slightly more complicated than my earlier answer - You need to find the first instance of the 'A' (using the INSTR function), then use LEFT in combination with REPLACE to replace just that instance, than use SUBSTRING and INSTR to find that same 'A' you're replacing and CONCAT it with the previous string.
See my test below:
SET #string = 'this is A string with A replace and An Answer';
SELECT #string as actual_string
, CONCAT(REPLACE(LEFT(#string, INSTR(#string, 'A')), 'A', 'B'), SUBSTRING(#string, INSTR(#string, 'A') + 1)) as new_string;
Produces:
actual_string new_string
--------------------------------------------- ---------------------------------------------
this is A string with A replace and An Answer this is B string with A replace and An Answer
Alternatively, you could use the functions LOCATE(), INSERT() and CHAR_LENGTH() like this:
INSERT(originalvalue, LOCATE('A', originalvalue), CHAR_LENGTH('A'), 'B')
Full query:
UPDATE wp_posts
SET post_content = INSERT(originalvalue, LOCATE('A', originalvalue), CHAR_LENGTH('A'), 'B');
With reference to https://dba.stackexchange.com/a/43919/200937 here is another solution:
UPDATE wp_posts
SET post_content = CONCAT( LEFT(post_content , INSTR(post_content , 'A') -1),
'B',
SUBSTRING(post_content, INSTR(post_content , 'A') +1))
WHERE INSTR(post_content , 'A') > 0;
If you have another string, e.g. testing then you need to change the +1 above to the according string length. We can use LENGTH() for this purpose. By the way, leave the -1 untouched.
Example: Replace "testing" with "whatever":
UPDATE wp_posts
SET post_content = CONCAT( LEFT(post_content , INSTR(post_content , 'testing') -1),
'whatever',
SUBSTRING(post_content, INSTR(post_content , 'testing') + LENGTH("testing"))
WHERE INSTR(post_content , 'testing') > 0;
By the way, helpful to see how many rows will be effected:
SELECT COUNT(*)
FROM post_content
WHERE INSTR(post_content, 'A') > 0;
If you are using an Oracle DB, you should be able to write something like :
UPDATE wp_posts SET post_content = regexp_replace(post_content,'A','B',1,1)
See here for more informations : http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions130.htm
Note : you really should take care of post_content regarding security issue since it seems to be an user input.
Greg Reda's solution did not work for me on strings longer than 1 character because of how the REPLACE() was written (only replacing the first character of the string to be replaced). Here is a solution that I believe is more complete and covers every use case of the problem when defined as How do I replace the first occurrence of "String A" with "String B" in "String C"?
CONCAT(LEFT(buycraft, INSTR(buycraft, 'blah') - 1), '', SUBSTRING(buycraft FROM INSTR(buycraft, 'blah') + CHAR_LENGTH('blah')))
This assumes that you are sure that the entry ALREADY CONTAINS THE STRING TO BE REPLACED! If you try replacing 'dog' with 'cat' in the string 'pupper', it will give you 'per', which is not what you want. Here is a query that handles that by first checking to see if the string to be replaced exists in the full string:
IF(INSTR(buycraft, 'blah') <> 0, CONCAT(LEFT(buycraft, INSTR(buycraft, 'blah') - 1), '', SUBSTRING(buycraft FROM INSTR(buycraft, 'blah') + CHAR_LENGTH('blah'))), buycraft)
The specific use case here is replacing the first instance of 'blah' inside column 'buycraft' with an empty string ''. I think a pretty intuitive and natural solution:
Find the index of the first occurrence of the string that is to be replaced.
Get everything to the left of that, not including the index itself (thus '-1').
Concatenate that with whatever you are replacing the original string with.
Calculate the ending index of the part of the string that is being replaced. This is easily done by finding the index of the first occurrence again, and adding the length of the replaced string. This will give you the index of the first char after the original string
Concatenate the substring starting at the ending index of the string
An example walkthrough of replacing "pupper" in "lil_puppers_yay" with 'dog':
Index of 'pupper' is 5.
Get left of 5-1 = 4. So indexes 1-4, which is 'lil_'
Concatenate 'dog' for 'lil_dog'
Calculate the ending index. Start index is 5, and 5 + length of 'pupper' = 11. Note that index 11 refers to 's'.
Concatenate the substring starting at the ending index, which is 's_yay', to get 'lil_dogs_yay'.
All done!
Note: SQL has 1-indexed strings (as an SQL beginner, I didn't know this before I figured this problem out). Also, SQL LEFT and SUBSTRING seem to work with invalid indexes the ideal way (adjusting it to either the beginning or end of the string), which is super convenient for a beginner SQLer like me :P
Another Note: I'm a total beginner at SQL and this is pretty much the hardest query I've ever written, so there may be some inefficiencies. It gets the job done accurately though.
I made the following little function and got it:
CREATE DEFINER=`virtueyes_adm1`#`%` FUNCTION `replace_first`(
`p_text` TEXT,
`p_old_text` TEXT,
`p_new_text` TEXT
)
RETURNS text CHARSET latin1
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'troca a primeira ocorrencia apenas no texto'
BEGIN
SET #str = p_text;
SET #STR2 = p_old_text;
SET #STR3 = p_new_text;
SET #retorno = '';
SELECT CONCAT(SUBSTRING(#STR, 1 , (INSTR(#STR, #STR2)-1 ))
,#str3
,SUBSTRING(#STR, (INSTR(#str, #str2)-1 )+LENGTH(#str2)+1 , LENGTH(#STR)))
INTO #retorno;
RETURN #retorno;
END
Years have passed since this question was asked, and MySQL 8 has introduced REGEX_REPLACE:
REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])
Replaces occurrences in the string expr that match the regular
expression specified by the pattern pat with the replacement string
repl, and returns the resulting string. If expr, pat, or repl is NULL,
the return value is NULL.
REGEXP_REPLACE() takes these optional arguments:
pos: The position in expr at which to start the search. If omitted, the default is 1.
occurrence: Which occurrence of a match to replace. If omitted, the default is 0 (which means “replace all occurrences”).
match_type: A string that specifies how to perform matching. The meaning is as described for REGEXP_LIKE().
So, assuming you can use regular expressions in your case:
UPDATE wp_posts SET post_content = REGEXP_REPLACE (post_content, 'A', 'B', 1, 1);
Unfortunately for those of us on MariaDB, its REGEXP_REPLACE flavor is missing the occurrence parameter. Here's a regex-aware version of Andriy M's solution, conveniently stored as a reusable function as suggested by Luciano Seibel:
DELIMITER //
DROP FUNCTION IF EXISTS replace_first //
CREATE FUNCTION `replace_first`(
`i` TEXT,
`s` TEXT,
`r` TEXT
)
RETURNS text CHARSET utf8mb4
BEGIN
SELECT REGEXP_INSTR(i, s) INTO #pos;
IF #pos = 0 THEN RETURN i; END IF;
RETURN INSERT(i, #pos, CHAR_LENGTH(REGEXP_SUBSTR(i, s)), r);
END;
//
DELIMITER ;
It's simpler
UPDATE table_name SET column_name = CONCAT('A',SUBSTRING(column_name, INSTR(column_name, 'B') + LENGTH('A')));
For MYSQL version pre-5.6 and 8.0, I've used this pattern to fix my issue, it's a bit gross, but I hope it helps some of you guys:
SET #string = 'I love shop it is a terrific shop, I love eveything about it';
SET #shop_code = 'shop';
SET #shop_date = CONCAT(#shop_code, '__', DATE_FORMAT(NOW(), '%Y_%m_%d__%Hh%im%ss'));
SET #part1 = SUBSTRING_INDEX(#string, #shop_code, 1);
SET #shop_nb = ROUND( (LENGTH(#string) - LENGTH(REPLACE(#string, #shop_code,''))) / LENGTH(#shop_code) );
SET #part2 = SUBSTRING_INDEX(#string, #shop_code, -#shop_nb);
SET #string = CONCAT(#part1, #shop_date, #part2);
SELECT #string;
To keep the sample of gjreda a bit more simple use this:
UPDATE wp_post
SET post_content =
CONCAT(
REPLACE(LEFT(post_content, 1), 'A', 'B'),
SUBSTRING(post_content, 2)
)
WHERE post_content LIKE 'A%';