mysql php query string contains words that start with input - mysql

Is there a built in way in mysql to query columns that contains specific word(s) and the word(s) also start with the input.
For instance, input is "EF"
#1 ABCD EFGH <- Want this one
#2 BCDE FGHA
#3 CDEF GHAB
#4 EFGH ABCD <- And this one
If I query %EF%, it'll give me the #1, #3 and #4, if I query EF%, it's only going to give #4.
So essentially, I want to know if mysql can firstly do a preg_split like in PHP, then query EF%, or something along the line of that.

Use a regular expression. In MySQL, the regexp pattern [[:<:]] matches the beginning of a word, so you can do:
WHERE column REGEXP '[[:<:]]EF'
Documentation

Answering my own question here. Just came up with a solution, not pretty but it works.
I just changed my parameter into this
((Column LIKE '%...%' AND Column LIKE '% ...%') Or (Column LIKE '...%')) AND ...
Going to leave this here for a day and see if anyone has a better solution.

If your column has two words, then you can use SUBSTR() and LOCATE().
+--------------------------------+
| MyColumn |
+--------------------------------+
| Apple Effect |
| Effortless Orange |
+--------------------------------+
.
SELECT *
FROM (
SELECT
*,
SUBSTR(#values,1,LOCATE(' ',MyColumn)-1) AS FirstWord
SUBSTR(#values,LOCATE(' ',#values)+1) AS SecondWord
FROM MyTable
) AS X
WHERE FirstWord LIKE 'EF%'
OR SecondWord LIKE 'EF%'
If your column has more than two words, then things are a little more complex, but you can use SUBSTRING_INDEX() to find the Nth instance.
+--------------------------------+
| MyColumn |
+--------------------------------+
| The Perfect Apple Effect |
| The Special Effortless Orange |
+--------------------------------+
.
SUBSTRING_INDEX(SUBSTRING_INDEX(#values,' ',4),' ',-1) = Gets the fourth word.
More examples and information can be found here.

Related

MySQL: SELECT DISTINCT REGEX value

In my MySQL database I have a row column called test_column with the following rows:
dtq test dis
ged something fbd
edf something tds
zhs nothing edk
dda anything zhg
hvf nothing ert
asf nothing vbg
I'm looking for the string between the first three and the last three characters. I can get these values with REGEX like this:
^\w{3}\s(\w+)\s\w{3}$
I want to SELECT DISTINCT these values.
Expected output is the following:
test
something
nothing
anything
How can I do that with a MySQL command?
If you are running MySQL 8.0, you can use regexp_replace() as follows:
select distinct regexp_replace(col, '(^\\w{3}\\s)|(\\s\\w{3}$)', '') new_col from mytable
This works by replacing the first and last words (and the following/preceding spaces) with the empty string. The first and last words must be 3 characters long.
Demo on DB Fiddle:
| new_col |
| :-------- |
| test |
| something |
| nothing |
| anything |
You can make the regex a little more generic so it accepts also starting and ending words that have a length other than 3 characters and sequences of more than one space:
regexp_replace(col, '(^\\w+\\s+)|(\\s+\\w{+$)', '')
Don't need a regexp if this suffices
SUBSTRING_INDEX(col, ' ', 2)
However, this assumes your "3 characters" or \w{3} (which is really 3 alphanumeric characters) is not really the test, but instead the space is critical.
You don't need regex if that is all you want (remove first 4 and last 4 characters):
SELECT DISTINCT SUBSTRING(test_column,5,LENGTH(test_column)-8)
FROM mytable
Demo on dbfiddle.uk
or everything after the first space, up until the second space:
SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(test_column,' ',2),' ',-1)
FROM mytable
Demo on dbfiddle.uk

MySQL delete lines that contains specific word

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

How can I match a dynamic route in the database?

I have a table like this:
// routes
+----+-----------------------------+
| id | route |
+----+-----------------------------+
| 1 | /tracking_code/expire/{id} |
| 2 | /tracking_code/list |
+----+-----------------------------+
{} means a dynamic value. And I need to match the first row for this entry value: /tracking_code/expire/2. I guess I need to use regexp. Any idea how can I do that?
My current workaround is using LIKE clause like this:
SELECT * FROM routes WHERE route LIKE :entry%
Also I should remove that number of the end of entry like /tracking_code/expire/.
Sadly my approach won't work for complicated routes like this: /tracking_code/expire/{id}/temp. Anyway, how should I use regexp for this?
You can use RLIKE like this
SELECT * FROM routes WHERE route RLIKE '^.*[0-9]+.*$'
to replace using regex i don't think this is possible, but there are some sneaky way, read this post here How to do a regular expression replace in MySQL?
MySql demo
Regex demo

MySql Regexp result word part of known word

Been struggling for this for awhile.
Is there a way to find all rows in my table where the word in the column 'word' is a part of a search word?
+---------+-----------------+
| id_word | word |
+---------+-----------------+
| 177041 | utvälj |
| 119270 | fonders |
| 39968 | flamländarens |
| 63567 | hänvisningarnas |
| 61244 | hovdansers |
+---------+-----------------+
I want to extract the row 119270, fonders. I want to do this by passing in the word 'plafonders'.
SELECT * FROM words WHERE word REGEXP 'plafonders$'
That query will of course not work in this case, would've been perfect if it had been the other way around.
Does anyone know a solution to this?
SELECT * FROM words WHERE 'plafonders' REGEXP concat(word, '$')
should accomplish what you want. Your regex:
plafonders$
is looking for plafonders at the end of the column. This is looking for everything the column has until its end, e.g. the regexp is fonders$ for 119270.
See https://regex101.com/r/Ytb3kg/1/ compared to https://regex101.com/r/Ytb3kg/2/.
MySQL's REGEXP does not handle accented letters very well. Perhaps it will work OK in your limited situation.
Here's a slightly faster approach (though it still requires a table scan):
SELECT * FROM words
WHERE 'PLAutvälj' =
RIGHT('PLAutvälj', CHAR_LENGTH(word)) = word;
(To check the accents, I picked a different word from your table.)

How can I use the LIKE operator on a list of strings to compare?

I have a query I need to run on almost 2000 strings where it would be very helpful to be able to do a list like you can with the "IN" operator but using the LIKE comparison operation.
For example I want to check to see if pet_name is like any of these (but not exact): barfy, max, whiskers, champ, big-D, Big D, Sally
Using like it wouldn't be case sensitive and it can also have an underscore instead of a dash. Or a space. It will be a huge pain in the ass to write a large series of OR operators. I am running this on MySQL 5.1.
In my particular case I am looking for file names where the differences are usually a dash or an underscore where the opposite would be.
For this task I would suggest making use of RegExp capabilities in MySQL like this:
select * from EMP where name RLIKE 'jo|ith|der';
This is case insensitive match and will save from multiple like / OR conditions.
You could do something like this -
SELECT FIND_IN_SET(
'bigD',
REPLACE(REPLACE('barfy,max,whiskers,champ,big-D,Big D,Sally', '-', ''), ' ', '')
) has_petname;
+-------------+
| has_petname |
+-------------+
| 5 |
+-------------+
It will give a non-zero value (>0) if there is a pet_name we are looking for.
But I'd suggest you to create a table petnames and use SOUNDS LIKE function to compare names, in this case 'bigD' will be equal to 'big-D', e.g.:
SELECT 'bigD' SOUNDS LIKE 'big-D';
+---------------------------+
| 'bigD'SOUNDS LIKE 'big-D' |
+---------------------------+
| 1 |
+---------------------------+
Example:
CREATE TABLE petnames(name VARCHAR(40));
INSERT INTO petnames VALUES
('barfy'),('max'),('whiskers'),('champ'),('big-D'),('Big D'),('Sally');
SELECT name FROM petnames WHERE 'bigD' SOUNDS LIKE name;
+-------+
| name |
+-------+
| big-D |
| Big D |
+-------+
As first step put all static values in any temporary table, this would be lookup dictionary.
SELECT * FROM Table t
WHERE EXISTS (
SELECT *
FROM LookupTable l
WHERE t.PetName LIKE '%' + l.Value + '%'
)
Configure the column containing those 2000 values for full-text searching. Then you can use MySQL's full-text search feature. Refer to their docs
You could use REGEXP instead. It worked like a charm for me
pet_name regexp 'barfy|max|whiskers|champ|you name it'