I have a search module with SQL query like this:
SELECT FROM trilers WHERE title '%something%'
And when I search for keyword for example like "spiderman" it returns not found, but when I search for "spider-man" it returns my content (original row in MySQL is "spider-man").
How can I ignore all symbols like -, #, !, : and return content with "spiderman" and "spider-man" keywords at the same time?
What you can do is replace the characters you don't care about before the search takes place.
First iteration would look like this:
SELECT * FROM trilers WHERE REPLACE(title, '-', '') LIKE '%spiderman%'
This would ignore any '-'.
Next you would rap that with another REPLACE to include '#' like this:
SELECT * FROM trilers WHERE REPLACE(REPLACE(title, '-', ''), '#', '') LIKE '%spiderman%'
For all 3 ('!','-','#') you would just increase the Replace with another Replace like this:
SELECT * FROM trilers WHERE REPLACE(REPLACE(REPLACE(title, '-', ''), '#', ''),'!','') LIKE '%spiderman%'
You could try something like
SELECT * FROM trilers WHERE replace(title, '-', '') LIKE '%spiderman%'
The other answers involving using REPLACE are great, but if you don't care what characters appear between "spider" and "man" or how many characters there are between the two strings, you can use an additional wildcard in your expression:
SELECT * FROM Superheroes WHERE HeroName LIKE '%spider%man%';
If you want to match only one character, but allow any character, you can use the _ wildcard, which matches only one character:
SELECT * FROM Superheroes WHERE HeroName LIKE '%spider_man%';
This will match "spideryman" and "spideryman in la la land" but not "spiderysupereliteuberheroman".
If you have a limited number of possible symbols, a way to do it without REPLACE is to use a disjunctive expression:
SELECT * FROM Superheroes WHERE
HeroName LIKE '%spiderman%'
OR
HeroName LIKE '%spider-man%'
OR
HeroName LIKE '%spider#man%'
OR
HeroName LIKE '%spider!man%';
WHERE trilers REGEXP '[[:<:]]spider[-#!:]?man[[:>:]]'
Some discussion:
[[:<:]] -- word boundary
[-#!:] -- character set, matches any of them. ('-' must be first)
[-#!:]? -- optional -- so that 'spiderman' will still match
This, unlike the rest of the answers, will avoid matching
spidermaniac
Also, consider using FULLTEXT.
You should be able to use your search with a small update. You should be able to do something like: SELECT FROM trilers WHERE title LIKE '%spider%'. This should search for anything where spider is before or after something else like the hyphen (-)
Related
I have a dictionary table 'dictionary', where column 'word' contains the list of all English words.
I want to find all words that contain specific alphabet characters only and exclude the rest of the alphabet. I am able to do so (see the example below), but as you can see, it is downright ugly.
EXAMPLE
Currently to find all words that contain letters 'a', 'b', 'c', 'x', 'y', 'z', but exlude rest of the alphabet letters I do this:
SELECT word
FROM dictionary
WHERE (
word LIKE '%a%'
OR word LIKE '%b%'
OR word LIKE '%c%'
OR word LIKE '%x%'
OR word LIKE '%y%'
OR word LIKE '%z%'
) AND (
word NOT LIKE '%d%'
AND word NOT LIKE '%e%'
AND word NOT LIKE '%f%'
AND word NOT LIKE '%g%'
AND word NOT LIKE '%h%'
AND word NOT LIKE '%i%'
AND word NOT LIKE '%j%'
AND word NOT LIKE '%k%'
AND word NOT LIKE '%l%'
AND word NOT LIKE '%m%'
AND word NOT LIKE '%n%'
AND word NOT LIKE '%o%'
AND word NOT LIKE '%p%'
AND word NOT LIKE '%q%'
AND word NOT LIKE '%r%'
AND word NOT LIKE '%s%'
AND word NOT LIKE '%t%'
AND word NOT LIKE '%u%'
AND word NOT LIKE '%v%'
AND word NOT LIKE '%w%' )
Any way to accomplish this task using some form of regex or other optimization?
Any tricks or hints would be much appreciated.
You can achieve it using REGEXP
SELECT `word `
FROM `dictionary`
WHERE `word` REGEXP '[abcxyzABCXYZ]'
AND `word` NOT REGEXP '[defghijklmnopqrstuvwDEFGHIJKLMNOPQRSTUVW]'
This is a better approach.
SELECT word
FROM dictionary
WHERE word REGEXP '.*[abcxyzABCXYZ].*$'
AND word NOT REGEXP '.*[defghijklmnopqrstuvwDEFGHIJKLMNOPQRSTUVW].*$';
Check This.
set #1='a'\\
set #2 ='b'\\
set #3 ='c'\\
set #4 ='x'\\
set #5 ='y'\\
set #6 ='z'\\
set #find=CONCAT(#1,#2,#3,#4,#5,#6)\\
set #ALl='abcxyzdefghijklmnopqrstuvw'\\ all alphabets here
set #ALl=replace(#ALl,#1,'')\\ replace alphabet that you want
set #ALl=replace(#ALl,#2,'')\\
set #ALl=replace(#ALl,#3,'')\\
set #ALl=replace(#ALl,#4,'')\\
set #ALl=replace(#ALl,#5,'')\\
set #ALl=replace(#ALl,#6,'')\\
SELECT word
FROM dictionary
WHERE word RLIKE CONCAT('.*[',#find,'].*$')
AND word NOT RLIKE CONCAT('.*[',#ALl,'].*$');\\
Check Demo Here
If you can't use REGEXP for some reason, then this should work too:
SELECT word
FROM dictionary
WHERE Replace(Replace(Replace(Replace(Replace(Replace(
word, 'a', ''),
'b', ''),
'c', ''),
'x', ''),
'y', ''),
'z', '') = ''
I doubt it will be very fast though. Then again, I'm not sure anything will be fast for this requirement =)
The test is simply:
word REGEXP '^[abcxyz]*$'
That says that everything from start (^) to end ($) must be a string of zero or more (*) of the characters ([]) abcxyz.
I did not include both lower and upper case on the presumption that you are using a case-insensitive collation.
There is no need for the AND .. NOT.
There is a possible problem: If you want to allow notw, do you want to match won't? That is, what should be done about punctuation?
(There may be other edge cases that are not adequately specified in the Question.)
WHERE Field not LIKE '%[^a-z0-9 .]%'
I have a field where I save strings, like:
"one two-tree"
"one-two-tree"
"one-two tree"
"one two tree"
When I do a SELECT, I want to retrieve strings that have either "-" or " " (space). Example:
When I do:
Select name from table where name="one two tree"
I want it to bring also results where there is either space or -, in this case returning all string exemplified above.
Is there a wildcard for this?
As far as standard SQL, you must use "or", or "like". depending on what exactly you want. EXAMPLE: Select name from table where name like "one?two?tree".
However, mySQL supports a REGEX extension that will give you what you want:
http://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html
One option is to use replace:
select name
from yourtable
where replace(name, '-', ' ') = 'one two tree'
There is, but it is slow: you can use REGEXP:
SELECT name
FROM table
WHERE name REGEXP 'one[- ]two[- ]tree'
or you can use replacements:
SELECT name
FROM table
WHERE REPLACE(name, '-', ' ') = 'one two three'
but your best bet is to make an additional column where you will have a normalised name (with dashes always replaced with spaces, for example) so you can take advantage of indices.
You can use the LIKE condition with '%' (wildcard operator) for this.
e.g.
SELECT name from table_name WHERE name LIKE '%-%' OR name LIKE '% %'
-- will return all names that have `-` or ` `.
Field X in table may contain special characters e.g hello!World and I would like to know if there is a way to match that with HelloWorld (Ignore case and special characters).
SELECT * FROM table WHERE X='Helloworld'
http://sqlfiddle.com/#!9/2afa1/1
if you need exaclty match of string:
SELECT *
FROM table1
WHERE x REGEXP '^hello[[:punct:],[:space:]]world$';
And if hello world could be a part of larger string:
SELECT *
FROM table1
WHERE x REGEXP 'hello[[:punct:],[:space:]]world';
What you can do is to replace all special characters like this:
SELECT * FROM table WHERE LOWER(REPLACE(X, '!', '')) = LOWER('HelloWorld');
Chain those replacements if you have to replace more:
SELECT * FROM table WHERE LOWER(REPLACE(REPLACE(X, '!', ''), '?', '')) = LOWER('HelloWorld');
If I understood your question right, you need to filter out non-ASCII characters? Please confirm whether this is true. In order to do that, have a look at REGEXP matching as in the comment link and this question.
Try something like
SELECT * FROM `table ` WHERE `X` REGEXP 'Helloworld';
REGEXP 'hello[^[:alpha:]]*world'
Notes:
This finds the string in the middle of other stuff; add ^ and $ to anchor to ends.
This assumes the non-alpha character(s) are between hello and world, not some other spot in the string.
This relies on the relevant collation to do (or not do) case folding.
Example of the problem:
SELECT * FROM `table`
WHERE `content`
RLIKE "[[:<:]]didnt[[:>:]]"
The problem is, when I search for things like "didnt", columns with "didn't" (with an apostrophe) arent found. And if I were to search for "didn't", columns with "didnt" (without an apostrophe) arent found.
What change do I need to make so that it ignores apostrophes, commas, hyphens, etc, and gives results regardless of if there are/arent apostrophes.
why don't you try with an |options
SELECT * FROM table
WHERE
(content RLIKE "[[:<:]]didnt[[:>:]]|[[:<:]]didn't[[:>:]]|[[:<:]]didn..t[[:>:]]|ETC)"
source: http://www.sqlines.com/mysql/regexp_rlike
You could use nested replace functions:
SELECT *
FROM `table`
WHERE
replace(replace(replace(`content`, '\'', ''), ',', ''), '-', '')
RLIKE "[[:<:]]didnt[[:>:]]"
In my table I have firstname and last name. Few names are upper case ( ABRAHAM ), few names are lower case (abraham), few names are character starting with ucword (Abraham).
So when i am doing the where condition using REGEXP '^[abc]', I am not getting proper records. How to change the names to lower case and use SELECT QUERY.
SELECT * FROM `test_tbl` WHERE cus_name REGEXP '^[abc]';
This is my query, works fine if the records are lower case, but my records are intermediate ,my all cus name are not lower case , all the names are like ucword.
So for this above query am not getting proper records display.
I think you should query your database making sure that the names are lowered, suppose that name is the name you whish to find out, and in your application you've lowered it like 'abraham', now your query should be like this:
SELECT * FROM `test_tbl` WHERE LOWER(cus_name) = name
Since i dont know what language you use, I've just placed name, but make sure that this is lowered and you should retrieve Abraham, ABRAHAM or any variation of the name!
Hepe it helps!
Have you tried:
SELECT * FROM `test_tbl` WHERE LOWER(cus_name) REGEXP '^[abc]';
I don't know since when, but nowadays MySql REGEXP is case insensitive.
https://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html
You don't need regexp to search for names starting with a specific string or character.
SELECT * FROM `test_tbl` WHERE cus_name LIKE 'abc%' ;
% is wildcard char. The search is case insensitive unless you set the binary attribute for column cus_name or you use the binary operator
SELECT * FROM `test_tbl` WHERE BINARY cus_name LIKE 'abc%' ;
A few valid options already presented, but here's one more with just regex:
SELECT * FROM `test_tbl` WHERE cus_name REGEXP '^[abcABC]';