Using a SQL wildcard ignoring non-alphanumeric characters in a column - mysql

I have a two-column table:
product name
cars ["bmw", "mazda", "ford", "dodge"]
fruit ["lemon", "orange", "lime", "apple"]
I'm using a wildcard to search the product's name column. My question is, is there a way to search a column only by alphanumeric characters and ignore the " and [ ]?
For example, if the user searched bmw the query would be: LIKE '%bmw%' and it would return cars, however if the user searches bmw" and the query is: LIKE '%bmw"% or they enter dodge"] and the query would be LIKE '%dodge"]%" it would want it to not return any results.
My current query:
SELECT product, name FROM `test1` WHERE name LIKE '%bmw%'
It doesn't need to be a wildcard basically, I am after the query only providing the product if the exact name is used but because of the format of the name column it's giving me problems.

You might want to clean the data before it's being added to the query.
e.g.You can use regex to replace unwanted characters / only allow certain characters in a text.
Then you can add that "cleaned" data as a parameter to that query.

As suggested JSON_SEARCH() is what I needed to achieve my desired outcome.
See: https://database.guide/json_search-find-the-path-to-a-string-in-a-json-document-in-mysql/
Specifically Example 5 – Wildcards.

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

How to match keywords with SQL query?

I am building a website that accepts user input keywords and output data that matches. For instance if the user specifies keyword as 'Restaurant pizza' then my database should output such record.
My current table has a column called category and five columns named from keyword1 to keyword5 which contains their specialized area, i.e. 'pizza', 'chicken' or 'bbq' etc.
But I have no idea how to write the SQL query since user may input keywords in any order: category first or with specialized area first.
so such query will surely return no result (given that user input 'Restaurant pizza' for query):
SELECT *
FROM message
WHERE category LIKE 'Restaurant pizza'
OR keyword1 LIKE 'Restaurant pizza'
OR keyword2 LIKE 'Restaurant pizza'
I guess it would be a bad idea splitting input keyword into words then running every word in the WHERE clause to database. but I really do not know how to achieve my goal.
In addition, would you please give me some advice on how to build index in this scenario?
You should create FULLTEXT index on category and keywords columns, then when querying data explode query string by delimeters (space character) and then create query something like:
SELECT * FROM items
WHERE
MATCH (category,keyword1,keyword2,keyword3,keyword4,keyword5)
AGAINST ('pizza')
AND
MATCH (category,keyword1,keyword2,keyword3,keyword4,keyword5)
AGAINST ('restaurant');
You may try this:
SELECT *
FROM message
WHERE `category` LIKE '%Restaurant%'
AND (`keyword1` IN ('Pizza','chicken','bbq')
OR `keyword2` IN ('Pizza','chicken','bbq'))

Search XML feed's description against a keyword from database

I'm working on a project where I use XML feeds to get input. I have to filter the items which title and description that matches specific keywords. If an item contains smart phone in title or description, I have to add that item in database under the category "Smart phone".
The query I use here is
$title = $item=>title;
$desc = $item->description;
SELECT cid FROM tbl_keyword WHERE MATCH(keyword) AGAINST ('".$title." ".$desc."' IN
BOOLEAN MODE);
Query returns value but it gets other rows from database like smart watch,smart toys.
I want to know, how to include space based search.
Query have to match the exact keyword.
table looks like
id cid keyword
1 6 smart phone
2 6 iphone
3 7 smart watch
When i get a title as "Smart phones are not essential", query should return only the cid 6.
How to implement it.?
As I know , you can't just search the whole sentence(Smart phones are not essential) against the db to get that exact result .
Two ways to do this :
1.*(Recommended)*You can just break the sentence with space ("Smart", "Phone", "are", "not", "essential")and then apply the following query
select * from tbl_keyword where keyword like "%smart%" or keyword like "%phones%" or keyword like "%are%" or keyword like "%not%" or keyword like "%essential%"
This query will output list of possible entries from the database. From this you will need to compare the result with your query sentence using your programming language.
2.This way will output the entry directly from the database (but this may rule out some of the important entries at worst case).
Breakdown the sentence into single word like this ("Smart", "Phones", "are", "not", "essential")
And then break this sentence with two words like this ("Smart Phones", "Phone are", "are not", "not essential","essential Smart","Smart are","Smart not","Phone not")
And use both of this to retrieve entries from the database (This process will just narrow down the filter)
select * from tbl_keyword where (keyword like "%smart%" or keyword like "%phone%" or keyword like "%are%" or keyword like "%not%" or keyword like "%essential%") and (keyword like "%smart phones%" or keyword like "%phones are%" or keyword like "%are not%" or keyword like "%not essentials%" or keyword like "%essentials smart%")
Hope this will help you ...

MySQL search within the last 5 characters in a column?

My user table has a column "name" which contains information like this:
Joe Lee
Angela White
I want to search for either first name or last name efficiently. First name is easy, I can do
SELECT * FROM user WHERE name LIKE "ABC%"
But for last name, if I do
SELECT * FROM user WHERE name LIKE "%ABC"
That would be extremely slow.
So I am thinking about counting the characters of the input, for example, "ABC" has 3 characters, and if I can search only the last three characters in name column, that would be great. So I want something like
SELECT * FROM user WHERE substring(name, end-3, end) LIKE "ABC%"
Is there anything in MySQL that can do this?
Thanks so much!
PS. I cannot do fulltext because our search engine doesn't support that.
The reason that
WHERE name LIKE '%ith'
is a slow way to look for 'John Smith' by last name is the same reason that
WHERE Right(name, InStr(name, ' ' )) LIKE 'smi%'
or any other expression on the column is slow. It defeats the use of the index for quick lookup and leaves the MySQL server doing a full table scan or full index scan.
If you were using Oracle (that is, if you worked for a formerly wealthy employer) you could use function indexes. As it is you have to add some extra columns or some other helping data to accelerate your search.
Your smartest move is to split your first and last names into separate columns. Several other people have pointed out good reasons for doing that.
If you can't do that you could try creating an extra column which contains the name string reversed, and create an index on that column. That column will have, for example, 'John Smith' stored as 'htimS nhoJ'. Then you can search as follows.
WHERE nameReversed LIKE CONCAT(REVERSE('ith'),'%')
This search will use the index and be decently fast. I've had good success with it.
You're close. In MySQL you should be able to use InStr(str, substr) and Right(str, index) to do the following:
SELECT * FROM user WHERE Right(name, InStr(name, " ")) LIKE "ABC%"
InStr(name, " ") returns the index of the Space character (you may have to play with the " " syntax). This index is then used in the Right() function to search for only the last name (basically; problems arise when you have multiple names, multiple spaces etc). LIKE "ABC%" would then search for a last name starting with ABC.
You cannot use a fixed index as names that are more than 3 or less than 3 characters long would not return properly as you suggest.
However, as Zane said, it's a much better practise to use seperate fields.
If it is a MyIsam table, you may use Free text search to do the same.
You can use the REGEXP operator:
SELECT * FROM user WHERE name REGEXP "ABC$"
http://dev.mysql.com/doc/refman/5.1/en/regexp.html

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.