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));
Related
So I have a slug column in my table and due to some bad coding, some of my slugs are messed up and need to be fixed.
I need to find all slugs that have a hyphen on both sides of exactly 5 digits, somewhere in the middle of the string.
So here's three samples of slugs:
321-sw-2nd-ave-portland-or-97204-2-3-4-5
321-sw-2nd-ave-portland-or-97204-2-3
430-e-25th-st-tacoma-wa-98421
My expression would match the first and second but not the third one.
I would like to then get rid of those extra things after the zip code.
Here's what I have tried so far, but my Regex skills are lacking big time.
^(.)*d{5}-(.)*$
You are attempting to match on the entire string. I would simply do a partial match on the part that you are interested in. Another problem with your regex is that you use d to represent a digit: MySQL wants \\d; also, this notation is only supported from 8.0 (in earlier versions, you need [0-9]).
Consider:
slug RLIKE '[0-9]{5}-'
Demo on DB Fiddle:
with t as (
select '321-sw-2nd-ave-portland-or-97204-2-3-4-5' slug
union all select '321-sw-2nd-ave-portland-or-97204-2-3'
union all select '430-e-25th-st-tacoma-wa-98421'
)
select slug from t where slug RLIKE '[0-9]{5}-'
| slug |
| :--------------------------------------- |
| 321-sw-2nd-ave-portland-or-97204-2-3-4-5 |
| 321-sw-2nd-ave-portland-or-97204-2-3 |
I have a MySQL database with a varchar column (although the column type can be changed if needed).
The column stores some ids separated with underscores like so:
Row 1: 1
Row 2: 1_2_3
Row 3: 10_2
Row 4: 4_5_1
Is there anyway in this structure to query that column for 1 and return all rows with 1 (but not Row 3 which contains 1 but the ID is 10).
To get the current results I am attempting to search the column LIKE %1%.
Or do I need to change the structure to achieve the result I want?
Maybe you can try:
select *
from t
where c like '1\_%'
or c like '%\_1'
or c like '%\_1\_%'
or c = '1'
You need to escape the underscore as \_, since SQL defines it as a wildcard and will match any character.
If we had a comma separator, then we could use MySQL FIND_IN_SET function.
We can use MySQL REPLACE function to change the underscores to commas,
e.g.
SELECT t.*
FROM t
WHERE FIND_IN_SET('1',REPLACE( t.id ,'_',','))
Reference:
https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_find-in-set
https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_replace
NOTE:
Storing underscore separated lists is an antipattern. See Chapter 2 of Bill Karwin's book "SQL Antipatterns: Avoiding the Pitfalls of Database Programming"
https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557
With the operator like:
select * from tablename
where concat('_', id, '_') like '%#_1#_%' escape '#'
See the demo.
Results:
| id |
| ----- |
| 1 |
| 1_2_3 |
| 4_5_1 |
I am trying to remove part of a string. But can't do it properly. String is like this: 4,290TL〜9,490TL So trying to remove after this 〜
I tried
UPDATE SET price = SUBSTRING_INDEX(price, '〜')
But not worked.
SUBSTRiNG_INDEX requires 3 parameters, the last one being the delimiter count. In this case you need to supply a count of 1, indicating that you want everything to the left of the first occurrence of the delimiter 〜. Additionally, you need to specify your table name in the query. Try this:
UPDATE yourtable SET price = SUBSTRING_INDEX(price, '〜', 1)
UPDATE SET price = SUBSTRING_INDEX(price, '〜', 1)
Please note the the strings you have shared with this question or comments uses DIFFERENT wavy line ("tilde") characters
# the tilde character used here is DIFFERENT to the next example
select substring_index('4,290TL〜9,490TL','〜',1)
;
+----+------------------------------------------------------+
| | substring_index('4,290TL〜9,490TL','〜',1) |
+----+------------------------------------------------------+
| 1 | 4,290TL |
# the tilde character is different to the one above
select substring_index('18,990万円(1戸)~28,790万円(1戸)','~',1)
;
+----+-----------------------------------------------------------+
| | substring_index('18,990万円(1戸)~28,790万円(1戸)','~',1) |
+----+-----------------------------------------------------------+
| 1 | 18,990万円(1戸) |
You will need to be CERTAIN the the tilde you use as delimiter is the one you use in substring_index() otherwise that function will just return the whole string.
I'm trying to delete lines in specific column from all rows that contains specific words.
For example:
Remove lines that contain word apple and it is always at the beginning of the line.
+--+------------------+
|ID|data |
+--+------------------+
|1 |sometext1 |
| |sometext2 |
| |apple sometext3 |
| |sometext4 |
+--+------------------+
|2 |apple sometext5 |
| |sometext6 |
+--+------------------+
so the result would be:
+--+------------------+
|ID|data |
+--+------------------+
|1 |sometext1 |
| |sometext2 |
| |sometext4 |
+--+------------------+
|2 |sometext6 |
+--+------------------+
'SometextX' is different in every line, number of lines is different in every row and it has different number of characters in every line.
I really need this in MySQL any help would be appreciated.
You would be better off using REGEXP here to match patterns in each line:
DELETE FROM yourTable WHERE text REGEXP '^apple';
REGEXP allows for fairly complex regex matching, and would be useful if your requirement changes or gets more complex later on.
Edit: MySQL has no built in support for regex replacement, so there is no easy way to accomplish what you want.
A general regex pattern to remove the word apple would be \bapple\b. You may search on this pattern and replace with empty string.
You would use where:
where textcol not like 'apple%' or textcol is null
This can be part of a select or a delete (the question mentions "result" which suggests the former and "delete" which suggests the latter). It is not clear whether you actually want to change the data or whether you just want the result set without these words.
Note: you can do this without or and still handle NULL values, because MySQL has a NULL-safe equality operator:
where not left(textcol, 5) <=> 'apple'
You can use MySQL functions to select the right rows and to update with new data as follows:
UPDATE `yourTable` SET `yourField` = REPLACE(yourField, 'apple', '') WHERE yourField LIKE '%apple%'
If you don't want to delete the whole row, you can run these 3 queries in this order
update your_table set text=replace(text,substring(text,#start:=locate('\napple',text),locate('\n',text,#start+1)-#start+1),'');
update your_table set text=if((#start:=locate('apple',text))=1,replace(text,substring(text,#start,locate('\n',text,#start+1)-#start+1),''),text);
update your_table set text=if((#start:=locate('apple',text))=1,replace(text,substring(text,locate('apple',text)),''),text);
update #1 will remove apple in the middle of the text (prefixed by \n)
update #2 will remove apple at the beginning of its row (nothing before) and having following rows
update #3 will remove remaining cases
I am using MySQL. In one of my table attributes, I have a serial number description like "SM,ST,SK" for one device.
When users enter SM or ST or SK, I want my query to return a result
My current query looks like that:
SELECT CONCAT(lvl1_id,',',lvl2_id)
FROM hier_menus
LEFT JOIN labels ON (hier_menus.id=label_id AND tbl=65 AND fld=2 AND lang_id=5)
WHERE
hm_type=13 AND lvl1_id=141 AND lvl2_id=id AND label='".addslashes($serial)."'";
It is only able to look at the first comma part of serial number column. When users enter ST, it will not return anything.
Is it possible to search the whole of the long string "SM,ST,SK" to return a matching row?
mysql> select find_in_set('SK', 'SM,ST,SK');
+-------------------------------+
| find_in_set('SK', 'SM,ST,SK') |
+-------------------------------+
| 3 |
+-------------------------------+
1 row in set (0.00 sec)
mysql> select find_in_set('SP', 'SM,ST,SK');
+-------------------------------+
| find_in_set('SP', 'SM,ST,SK') |
+-------------------------------+
| 0 |
+-------------------------------+
You are looking for find_in_set,
however, this is not an optimize solution
you should seek to normalize your serial number into another table,
where each SM,ST, and SK is stored as one row
another way is to convert the data type to set
Try FIND_IN_SET():
SELECT ... WHERE FIND_IN_SET($serial, label)
and as ajreal's pointed out, don't use addslashes. use mysql_real_escape_string (or whatever your DB abstraction library provides). addslashes is hopelessly broken and WILL allow someone to attack your database with ease.