Update when third character is "_" - mysql

I want to update column 1 in table A in a specific way: When the third character in the column is an "_" I want to insert the first 2characters, if the third character anythin else I want to leave it as it is.
Example:
|col1|
+--------+
|161_512 |
|16_1217 |
|161_512 |
|161512 |
|17_0117 |
|1615_12 |
Expected outcome:
|col1|
+--------+
|161_512 |
|16 |
|161_512 |
|161512 |
|17 |
|1615_12 |
Thats what I´ve got so far - but this is not working correctly:
UPDATE table A SET col1 = CASE WHEN col1 LIKE '%_%' THEN ... ELSE col1;

If you want to match a literal underscore in your LIKE expression, you will need to escape it using backslash. An unescaped underscore means match any single character. However, I would reword your query such that it uses a WHERE clause to determine whether or not to update a given record.
UPDATE table A
SET col1 = ...
WHERE col1 LIKE '__\_%'
Note carefully here that LIKE __\_% says to match any two characters, followed by a literal underscore, followed by anything else.
If you don't feel comfortable dealing with all this, you can always use a substring to check the value of the third character:
UPDATE table A
SET col1 = ...
WHERE SUBSTRING(col1, 3, 1) = '_'

When the third character in the column is an "_" I want to insert the first 2characters
I don't know what this means. First 2 characters from which attribute? Where do you want to insert them?
When the third character in the column is an "_"
That's simple. As you may already know, the underscore character is a wildcard matching exactly one character. Hence
LIKE '%_%'
will match any attribute with a at least one character. If you explicitly want to match an underscore character then you would escape the underscore
LIKE '%\_%'
And to require this to be the third character, perform a match on 2 single characters before it:
LIKE '__\_%'
(L I K E ' _ _ \ _ ')

Related

MySQL Query to extract only a specific value that not in a string

I have a data base column (comment) with almost any combination of alpha characters, numbers or alphanumerics can appear. In one example it looks like this this 55,44,1265,13,12 in another it might be 12,55,1265,44,13 there also might be A45, or 45A or ABCDE52JQST or 12 13 15 or anything really.
I need a MySQL query to extract any row based on a search entered by the user. For example the user might want to identify all rows with 12 in it. Not 1265 not 12A just 12, the only acceptable values other than 12 would be ,12 or 12, (comma12 or 12comma) or spaces before or after the number ( 12 or 12 ). But not 1265.
My current where clause looks like below and while it sometimes works, it sometimes doesn't and even if it did work every time, it's ugly. How else could I write the where clause to do what I need, could I use perl expressions in some way? Please give an example.
WHERE netID = $netID
AND
( comment LIKE '%$findit'
OR comment LIKE '$findit%'
OR comment = '$findit'
OR comment = ',$findit'
OR comment = '$findit,'
OR comment = ',$findit,'
OR comment LIKE '% $findit '
OR comment LIKE ' $findit %'
OR comment LIKE '%$findit,'
OR comment LIKE ',$findit%'
OR comment LIKE '%,$findit'
OR comment LIKE '$findit,%'
OR comment LIKE '%,$findit '
OR comment LIKE ' $findit,%'
OR comment LIKE '% $findit'
OR comment LIKE '$findit %'
OR comment LIKE '%$findit '
OR comment LIKE ' $findit%'
OR comment LIKE '%,$findit,%'
)
You seem to be describing set data with either commas or spaces as delimiters. Instead of going into the typical lecture on storage of serialised data, I will just assume there is nothing you can do about it.
Obviously, passing strings directly into your SQL like this poses a SQLi risk and you should be using parameterised queries or at least some robust sanitisation and validation of the user input.
So, treat the set as a set by turning the space separated lists into comma separated lists -
WHERE FIND_IN_SET('$findit', REPLACE(`comment`, ' ', ',')) > 0
FIND_IN_SET
REPLACE
PREPARED STATEMENTS
UPDATE
This db<>fiddle works for the examples you have provided. Please provide a specific example of value(s) for which this does not work. Using REGEXP as suggested by Kendle/Bill Karwin may be the better route to go down.
In MYSQL we can use regular expressions. Here we use the expression (?<![0-9])12(?![0-9]) which means that the string must contain 12 and, if the are characters before or after it, the one touching it must not be a number.
We use a negative lookback and a negative look forward.
create table base(
val varchar(100));
insert into base values
('55,44,1265,13,12'),
('12,55,1265,44,13'),
( 'A45, or 45A or '),
(' ABCDE52JQST 1265'),
('12 13 15 or a'),
('123,212, '),
('haza12'),
(1265),
(1212),
(12),
(2012);
select val from base
where val regexp
'(?<![0-9])12(?![0-9])'
| val |
| :--------------- |
| 55,44,1265,13,12 |
| 12,55,1265,44,13 |
| 12 13 15 or a |
| haza12 |
| 12 |
db<>fiddle here

REGEX_REPLACE not matching all chars from the beginning to the first occurrence of a 5 digits word

I've this record in a Mysql table:
ADDRESS
----------------------------------
sdasd 4354 ciao 12345 sdsdsa asfds
I would like to match all chars from the beginning to the first occurrence of a 5 digits word, including it.
In this case, using REGEXP_REPLACE, I would like to remove the substring matched and return sdsdsa asfds.
What I've tried to do is this:
SELECT REGEXP_REPLACE(ADDRESS, '^.+\b\d{5}\b.','') FROM `mytable`
The regexp seems to work testing it in this snippet and I cannot understand why Mysql won't.
MySQL supports POSIX regex which doesn't support PERL like properties e.g. \b, \d etc.
This regex should work for you:
SELECT REGEXP_REPLACE
('sdasd 4354 ciao 12345 sdsdsa asfds', '^.+[[:<:]][0-9]{5}[[:blank:]]+', '') as val;
+--------------+
| val |
+--------------+
| sdsdsa asfds |
+--------------+
RegEx Details:
^.+: Match 1 or more of any characters at the start (greedy)
[[:<:]]: Match a word boundary (zero width)
[0-9]{5}: Match exactly 5 digits
[[:blank:]]+: Match 1 or more of whitespaces (tab or space)

update string through part of string in case of appearance special event in string via MYSQL

I have a table with a varchar field that contains a description with variable lenght. I want to update it in the form shown below (delete the part after 20161203_ and before LC (1001_) in the first case) in case of appearance LC in string.
For example if the table contained:
|col1 |
+-----+
|20161512_NL_Luxus_1_DE |
|20161217_1001_LC_YoBirthdayNo_A_CH |
|20161512_NL_SDT_4_DE|
|20170117_2003_LC_YoBirthdayYes_A_DE |
I want a query that will return:
|result|
+------+
|20161512_NL_Luxus_1_DE|
|20161217_LC_YoBirthdayNo_A_CH|
|20161512_NL_SDT_4_DE|
|20170117_LC_YoBirthdayYes_A_DE |
I tried it like:
UPDATE table1 SET col1 = CASE WHEN col1 LIKE '%LC%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX(col1, '_', 1), '_', 2)
but that´s not correct...
Thanks in advance!
I also first attempted to do this using SUBSTRING_INDEX, but then gave up when it appeared that it only supports single character delimiters. My fallback solution is just to use a combination of INSTR and SUBSTRING. In the query below, I concatenate together the updated col1, in the process splicing out the four digit number which you want to remove.
UPDATE table1
SET col1 = CONCAT(SUBSTRING(col1, 1, 8), -- keep 8 digit date
SUBSTRING(col1, INSTR(col1, '_LC_'))) -- and everything from _LC_
WHERE col1 LIKE '%_LC_%' -- onwards

Replacing text in a MySQL query?

I have a column in my table, lets call it thecolumn. The values in that column are either a number, like 100036077, or a number followed by a name, like that 35921 John Doe.
I want to replace the names with nothing and add 1000 to the 5 numbers in front of that name (35921 John Doe --> 100035921) in my select. How can I do that without using any additional libraries? There is no native regex replace for MySQL, right?
Thanks!
This is a bit easy... or am I missing something?
SELECT CONCAT('1000',SUBSTRING_INDEX('35921 John Doe',' ',1))x;
+-----------+
| x |
+-----------+
| 100035921 |
+-----------+
The strategy here is to:
Get the substring from the beginning of the string up to the first space (which is the limit between the numeric part and the textual part)
Add the string "1000" to the string resulting of 1.
Replace current value with the string resulting from 2.
UPDATE thetable SET thecolumn =
CONCAT('1000', SUBSTRING_INDEX(thecolumn, ' ', 1));

"Where" statement: match a single word (not substring)

I am using MySQL.
I have a car table in my database, and there is a name column in that table.
Suppose the name column of the table contain values:
+----------+
| name |
+----------+
| AAA BB |
----------
| CC D BB |
----------
| OO kk BB |
----------
| PP B CC |
----------
I would like to search the table where name column value contains word "BB" (not substring), What is the SQL command to achieve this ?
I know LIKE , but it is used to match a contained substring, not for a word match.
P.S.
My table contains large data. So, I probably need a more efficient way than using LIKE
The values in name column are random strings.
Please do not ask me to use IN (...) , because the values in that column is unpredictable.
Try this WHERE clause:
WHERE name LIKE '% BB %'
OR name LIKE 'BB %'
OR name LIKE '% BB'
OR name = 'BB'
Note that this will not perform well if your table is large. You may also want to consider a full-text search if you need better performance.
You can use the REGEXP operator in MySQL:
SELECT *
FROM car
WHERE name REGEXP '[[:<:]]BB[[:>:]]'
It will match BB if it occurs as a single word. From the MySQL manual:
[[:<:]], [[:>:]]
These markers stand for word boundaries. They match the beginning and end of words, respectively. A word is a sequence of word characters that is not preceded by or followed by word characters. A word character is an alphanumeric character in the alnum class or an underscore (_).
mysql> SELECT 'a word a' REGEXP '[[:<:]]word[[:>:]]'; -> 1
mysql> SELECT 'a xword a' REGEXP '[[:<:]]word[[:>:]]'; -> 0