MySQL LIKE - partial match with up tp 2 different characters - mysql

Trying to look for partial matches:
SELECT * FROM watches_check WHERE modelNumber LIKE
'URL'
sample data:
URL: http://www.domain.com/s/keywords=AK-1470GBST&id=123456
modelNumber: AK-1470GBST
I'd like to find if the modelNumber is in URL field but it returns 0 results all the time.
Where did I go wrong?
Also, would it be possible to find partial matches, where there is say 1 or 2 characters different, for example AK-1470GBST vs AK/1470GBST ('/' instead of '-') will be considered a match

You can use
SELECT * FROM watches_check WHERE INSTR(URL, modelNumber) > 0
to check if your url contains the modelNumber. This will even work, if your modelNumber contains the wild cards for LIKE patterns : % and _.
It won't return partial matches. Have a look at Gordons answer for that.

The answer to your first question is to get the SQL correct. I think you want:
SELECT *
FROM watches_check
WHERE URL like concat('%', modelNumber, '%');
Note: The single quotes were removed from "URL" and wildcards were added to the search.
The answer to your second question is a technique called Levenshtein distance (see the Wikipedia page here). If you google "Levenshtein mysql" you will find various implementations of the algorithm.

Related

What is the best way to use MYSQL Search on term not working

What is the best way to search a database for a phrase such as "Almond Anise Cookie" and return the result?
If I
SELECT *
FROM recipes
WHERE name LIKE '%".$query."%'
and use the phrase "Almond Cookie", nothing is returned as expected. But if I search for "Anise Cookie" the result above is returned.
I've also tried
SELECT *
FROM recipes
WHERE name LIKE '%".$query."%'
OR name LIKE '".$query."%'
OR name LIKE '%".$query."'
with the same failed result.
Using MATCH AGAINST returns everything that contains "Almond" and everything that contains "Cookie" also not a good result. Is there a happy middle in returned results?
You can try using REPLACE. Something like this should work:
SELECT *
FROM recipes
WHERE NAME LIKE REPLACE(' ".$query." ',' ','%');
Note that I purposely add spaces between .$query. to ensure that the replace operation will make your term filled with the wildcard symbol. In the example above:
If $query='almond cookies' then REPLACE(' ".$query." ',' ','%') will become %almond%cookies%.
You can test the fiddle here : https://www.db-fiddle.com/f/kMzp99S8ENbTkYcW5FVdYN/0

Issue with RegExp matching a phone number format in query

I am trying to write a RegExp for MySQL that will only return the following 3 phone formats:
+1 000-000-0000 x0000
+1 000-000-0000
000-000-0000 x0000
000-000-0000
So basically:
+[any number of digits][space][any three digits]-[any three digits]-[any four digits][space][x][any number of digits]
The country code and the extension are optional. I am new to these but I would think this should return at least a number including both country code and extension options, but I get 0 results when I execute it.
\x2B[0-9]*\x20[0-9]{3}\-[0-9]{3}\-[0-9]{4}\x20x[0-9]+|
\x2B[0-9]*\x20[0-9]{3}\-[0-9]{3}\-[0-9]{4}|
[0-9]{3}\-[0-9]{3}\-[0-9]{4}
Can someone tell me why I am getting 0 results even though I have records like +1 555-555-5555 x5555 in my db. Also what is the syntax to make the country code and the extension are optional
Please note I am using [0-9] because I am querying a text field and \d didn't seem to return anything even when my criteria was something simple like \d*
So, as a joint effort, turns out the answer is here:
SELECT * FROM table
WHERE field
REGEXP '(^[+][0-9]+\ )?([0-9]{3}\-[0-9]{3}\-[0-9]{4})(\ x[0-9]+$)?'
First was the fact that character codes in mysql (x20, x2B and the like) are not allowed. Next important step was the use of parenthesis and the "?" token to make the different sections optional.
============
I think the issue is the lack of parenthesis to define the subexpressions.
This seems to work out for me, though it doesn't look real pretty:
SELECT '+1 000-000-0000 x0000' REGEXP '^(([+][0-9]*\[ ][0-9]{3}\-[0-9]{3}\-[0-9]{4}[ ]x[0-9]+)|())$'
as does
SELECT '' REGEXP '^(([+][0-9]*\[ ][0-9]{3}\-[0-9]{3}\-[0-9]{4}[ ]x[0-9]+)|())$'
as does (plain phone number):
SELECT '555-555-5555' REGEXP '^(([+][0-9]*\[ ])*[0-9]{3}\-[0-9]{3}\-[0-9]{4}([ ]x[0-9]+)*)|())$'
EDIT: (same regexp as above, but testing against version w/ country code and extension):
SELECT '+1 555-555-5555 x55' REGEXP '^(([+][0-9]*\[ ])*[0-9]{3}\-[0-9]{3}\-[0-9]{4}([ ]x[0-9]+)*)|())$'
When I try yours:
SELECT '+1 000-000-0000 x0000' REGEXP '\x2B[0-9]*\x20[0-9]{3}\-[0-9]{3}\-[0-9]{4}\x20x[0-9]+|'
I get:
1139 - Got error 'empty (sub)expression' from regexp

MySQL String Comparison with Wildcards

I wrote a query where a user can input a string and get the data related to that string back from the database.
For example, a user will input Apple even though the full name is Apple Inc.
The code would be laid out as so...
and Description like '%Apple%'
The problem with this is, it will return Snapple along with Apple.
Aside from removing the first "%" wildcard and making the user type more, how can I limit the results to just Apple?
Use a regular expression:
WHERE Description RLIKE '[[:<:]]apple[[:>:]]'
[[:<:]] matches the beginning of a word, [[:>:]] matches the end of a word.
See the documentation for all the regexp operators supported by MySQL
Firstly - string comparison with wild cards (especially leading wild cards) doesn't really scale using "like". You might want to look at full-text searching instead. This basically gives you "google-like" text searching capabilities.
To answer your question, in most cases, "Apple" is a better match than "Snapple" for the term "apple". So, you could include the concept of "match quality" in the search - something like:
select *, 10 as MatchQuality
from table
where description like 'Apple'
union
select *, 5 as MatchQuality
from table
where description like 'Apple%'
union
select *, 1 as MatchQuality
from table
where description like '%Apple%'

MySQL Find similar strings

I have an InnoDB database table of 12 character codes which often need to be entered by a user.
Occasionally, a user will enter the code incorrectly (for example typing a lower case L instead of a 1 etc).
I'm trying to write a query that will find similar codes to the one they have entered but using LIKE '%code%' gives me way too many results, many of which contain only one matching character.
Is there a way to perform a more detailed check?
Edit - Case sensitive not required.
Any advice appreciated.
Thanks.
Have a look at soundex. Commonly misspelled strings have the same soundex code, so you can query for:
where soundex(Code) like soundex(UserInput)
use without wildcard % for that
SELECT `code` FROM table where code LIKE 'user_input'
thi wil also check the space
SELECT 'a' = 'a ', return 1 whereas SELCET 'a' LIKE 'a ' return 0
reference

MySQL query - select postcode matches

I need to make a selection based on the first 2 characters of a field, so for example
SELECT * from table WHERE postcode LIKE 'rh%'
But this would select any record that contains those 2 characters at any point in the "postcode" field right? I am in need of a query that just selects the first 2 characters. Any pointerS?
Thanks
Your query is correct. It searches for postcodes starting with "rh".
In contrast, if you wanted to search for postcodes containing the string "rh" anywhere in the field, you would write:
SELECT * from table WHERE postcode LIKE '%rh%'
Edit:
To answer your comment, you can use either or both % and _ for relatively simple searches. As you have noticed already, % matches any number of characters whereas _ matches a single character.
So, in order to match postcodes starting with "RHx " (where x is any character) your query would be:
SELECT * from table WHERE postcode LIKE 'RH_ %'
(mind the space after _). For more complex search patterns, you need to read about regular expressions.
Further reading:
http://dev.mysql.com/doc/refman/5.1/en/pattern-matching.html
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
LIKE '%rh%' will return all rows with 'rh' anywhere
LIKE 'rh%' will return all rows with 'rh' at the beginning
LIKE '%rh' will return all rows with 'rh' at the end.
If you want to get only first two characters 'rh', use MySQL SUBSTR() function
http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_substr
Dave, your way seems correct to me (and works on my test data). Using a leading % as well will match anywhere in the string which obviously isn't desirable when dealing with postcodes.