I have a table with 3 columns something like below,
expert table
id - 1589
name - Jhonny
expert_in - 1,12,8 (Values similar like this)
The experts_in contains another table's foreign key
experts_in table
id - 1
expert_in - painting
I want search experts who are expert in some jobs while searching for experts
SELECT * FROM `experts` WHERE expert_in LIKE 1%
The above query brings all experts with 11,12,13...etc. I want only exact word. I know LIKE will bring all. Is there any way to achieve this without altering table. Thanks in advance.
You should use REGEXP. Try this query:
SELECT * FROM experts
WHERE expert_in REGEXP '[[:<:]]1[[:>:]]';
Output: See Live Demo on SQLFiddle
Note: You can adjust searching string based on your requirement above REGEXP is searching exact word.
if you can alter the data (not the table/schema) you should append and prepend another comma, so you can search with where col like "%,123,%", this will always fit on an exact value. Otherwise you have to use regex with something like ,?123,?
Related
I am trying to make sort of a search engine that searched through JSON values in my Database.
I have a table with a column called data in data there is a JSON string, example:
{"type_geld":"cash","bedrag":15.0,"totaal":8899.0,"reden":"itemshop-bought-item","citizenid":"EHT44095","steamnaam":"Finn"}
Now I want to search through the key steamnaam I am currently using this query:
SELECT * FROM logs_1 WHERE JSON_CONTAINS(lower(`data`), '"finn"', "$.steamnaam")
This does give me the rows that contain finn as a value in the steamname JSON.
But now I want to also make it check if it's not exactly the same, but almost the same. So basically a LIKE search. Can I achieve this with JSON_CONTAINS or something like that?
So if I type fin instead of finn I also want it to list the rows because it almost matches finn.
I tried a lot of things, but could not figure it out, hope someone has the solution for me! Thank you.
The solution I found:
Apparently after googling a bit more, I found this query, that exactly does what I want:
SELECT * FROM logs_1 WHERE JSON_EXTRACT(lower(`data`), "$.steamnaam") LIKE "%fin%"
The only concern I have if this will stay fast with a lot of rows..
SELECT *
FROM logs_1
WHERE data->>'$.steamnaam' LIKE '%fin%' /* COLLATE according CI collation */
I need to find entries that contain more than 7 numbers in one of my mysql tables BUT the numbers are separated by letters or anything else.
What I have is this little piece of code I use to find entries like dsc123456789:
select * from crawl where title regexp '[0-9]{7}'
How can I find entries like dsc-123-456_78B9? I tried different things but without success so far.
Thanks
You can use the following solution:
SELECT *
FROM crawl
WHERE title REGEXP '(([^[:digit:]])?[[:digit:]]){8,}';
Why the original query of the answer doesn't work?
-- this query doesn't work!
SELECT *
FROM crawl
WHERE title REGEXP '\d([^\d]?\d){7,}'
MySQL can't use character groups like \d (digits). So the query fails every time. On PHP and other languages the regular expression would look like this:
\d([^\d]?\d){7,}
but on MySQL this isn't valid. So you have to use the character classes of MySQL to solve this:
(([^[:digit:]])?[[:digit:]]){8,}
Hint: Make sure you use {8} or {8,} instead of {7} since you want to find all entries with more than 7 numbers / digits.
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
I have the following query :
SELECT * FROM `user`
WHERE MATCH (user_login) AGAINST ('supriya*' IN BOOLEAN MODE)
Which outputs all the records starting with 'supriya'.
Now I want something that will find all the records ending with e.g. 'abc'.
I know that * cannot be preappended and it doesn't work either and I have searched a lot but couldn't find anything regarding this.
If I give query the string priya ..it should return all records ending with priya.
How do I do this?
Match doesn't work with starting wildcards, so matching with *abc* won't work. You will have to use LIKE to achieve this:
SELECT * FROM user WHERE user_login LIKE '%abc';
This will be very slow however.
If you really need to match for the ending of the string, and you have to do this often while the performance is killing you, a solution would be to create a separate column in which you reverse the strings, so you got:
user_login user_login_rev
xyzabc cbazyx
Then, instead of looking for '%abc', you can look for 'cba%' which is much faster if the column is indexed. And you can again use MATCH if you like to search for 'cba*'. You will just have to reverse the search string as well.
I believe the selection of FULL-TEXT Searching isn't relevant here. If you are interested in searching some fields based on wildcards like:
%word% ( word anywhere in the string)
word% ( starting with word)
%word ( ending with word)
best option is to use LIKE clause as GolezTrol has mentioned.
However, if you are interested in advanced/text based searching, FULL-TEXT search is the option.
Limitations with LIKE:
There are some limitations with this clause. Let suppose you use something like '%good' (anything ending with good). It may return irrelevant results like goods, goody.
So make sure you understand what you are doing and what is required.
I want search companies from my company table when i give company name...here am using like operator
eg: saravana stores
it gives the result saravana stores texttiles,saravana stores thanga maligai,etc(which is contained with saravana stroes...coz of using LIKE operator)
Now my problem is when i give lcd projectors in the companyname, also want to fetch the records which are contained with the only projector word...but like operator gave the results with the 'lcd projector'
am making clear?
Try:
WHERE (name LIKE '%saravana%' OR name LIKE '%stores%')
This has two disadvantages:
It can't use an index so it will be slow.
It can give you matches you don't want like 'bestorest' matches '%stores%'.
You might want to use a full text search instead. You could also consider an external engine such as Lucene.
If you want proper fultext search, I highly recommend trying Lucene or Sphinx.
I know it would get a little complicated, but it's worth it for the end result.
Mark Byers is right.
To get more efficiency
After query dividing to words you can modify search input to get word base and unify searching to get smth lika:
WHERE (name LIKE '%sarava%' OR name LIKE '%stor%')