Improve on MySQL LIKE operator - php

I have a search form using a single text input with PHP, MySQLi.
Users search for names of people. In the MySQL table is a column 'name' and also a column 'nameNoSpaces' - this value is used when matching a user's search.
On input, the users query is stripped of all whitespace so that it also has no spaces. then I use the LIKE operator to compare the user's input (with no spaces) to the column 'nameNoSpaces'.
SELECT * FROM table WHERE nameNoSpaces LIKE '%query%'
If a value in 'nameNoSpaces' contains any part of the query string, it will be matched.
E.G. query 'hello you' will be matched to the value 'goodhelloyou'.
But not : query 'you hello'
I want to improve the search capabilities so that 'you hello' will return the row containing 'goodhelloyou'.
I have achieved this with PHP (foreach word do 'LIKE '%word%' and return all names that match every word).
BUT I was wondering if there is simply a SQL operator I can use to achieve this??
Thanks

SELECT * FROM table WHERE nameNoSpaces LIKE '%hello%you%'

Figured it out...should of seen it before
SELECT * FROM table WHERE name LIKE '%word1%' AND name LIKE '%word2%'....'%wordn%'
put all words into an array and use a foreach loop to create the query

Related

search exact string exist within column mysql

I'm using below sql query for search values from db, but when I search 'study' it will returns the values 'caese-study', 'get-study-materials' as well.
How can I use a query to search exact contains withing string column?
$names = 'study';
and the names column has values like comma separated,
Ex: 'study, abc, new' so I need to search within that too
SELECT * FROM datatitle WHERE names LIKE '%$names %' ;
SELECT * FROM datatitle WHERE names regexp '(^|[[:space:]])$names([[:space:]]|$)';
I try with above two queries but didnt work as expect, pls advice?
You should not be storing comma-separated values in a column. You should be using a junction/association table. You should fix the data model, if you can.
However, sometimes we cannot control other people's really bad decisions. MySQL has find_in_set():
SELECT dt.*
FROM datatitle dt
WHERE find_in_set(?, names) > 0;
Note that I have replaced the constant $names with a parameter. You should learn to use parameters to pass values into queries.

Matching json array from mysql table

i have a column in my users database called "tags" which could look like this:
`[1,2,3,4]`
That array only has numbers.
I am now wondering if I can select from the database where the json array has specific value in it. For example:
`SELECT * FROM users WHERE tags = "HAS 1 IN ARRAY"`
I was testing by just matching the number 1 but then it will probably return values with 10 to 19 if any user has number 10-19 in that array.
Try this:
SELECT * FROM users WHERE tags REGEXP '[[:<:]]1[[:>:]]';
For more info, see docs Regular Expressions.
PS I would recommend to decompose table, move tags into dependent table. On large table regexp will be slow...

Querying a table where the field contains any order of given text strings

I want to query a table as follows:
I have a field called "category" and my input match contains N separate words. I want the query to match all rows that contain all N words, but in any order.
For example if the field category contains "hello good morning world", my input query can contain "hello morning" or "good" or "world hello" and all are matches to the query.
How do I formulate such an SQL expression?
Also it would be good if the query can be made case insensitive.
If you are using MySQL you can use the boolean fulltext search feature to achieve this. You can put a + in front of each term and then only results with all the terms, in any order, will be returned. You will need to make sure the column containing the category field has a fulltext index specified on it for this to work. Other database engines probably have similar features. So for example you might do something like the following assuming there were a fulltext index over the category column...
SELECT * FROM myTable WHERE MATCH (category) AGAINST ('+term1 +term2 +term3' IN BOOLEAN MODE);
I would avoid using the "LIKE" operator as others have suggested you would have to worry about the headache of mixed upper/lower case and if you have a large database using a % in the front of a LIKE search term is going to cause a full table scan instead of using an index which is horrible for performance.
I'm not writing the loop that will build this query for you. This will get the job done, but it will be pretty inefficient.
SELECT * FROM table
WHERE (
TOUPPER(category) LIKE '*HELLO*' AND
TOUPPER(category) LIKE '*GOOD*' AND
TOUPPER(category) LIKE '*MORNING*' AND
TOUPPER(category) LIKE '*WORLD*'
);
You could also research using REGEXes with SQL.

Any Other Faster Execution Method For This MYSQL search query?

I have 100K datas in my mysql database, I want to search a query in it. I removed stop-words and splitted it into an array of keywords and stored in a variable ie $key[0],$key[1],$key[2].I am using the following query
SELECT *
FROM `table`
WHERE (`column` LIKE '%$key1%'
OR `column` LIKE '%$key2%'
OR `column` LIKE '%$key3%');
is any other faster ways to do the same.
The only way to speed up queries like this is to use full-text searching. LIKE '%string%' can't be optimized with normal indexes, because they use B-trees that depend on matching the prefix of the string being searched for. Since your pattern begins with a wildcard, the index doesn't help.
Another solution is to normalize your database. Don't put the keywords all in one column, put them in another table, with a foreign key to this table and a row for each FK+keyword. Then you can use a join to match the keywords.
Also, you're using the wrong type of quotes around your column names. They should be backticks, not single quotes.
you can do something like this
SELECT *
FROM table
WHERE colomn REGEXP '$key1|$key2|$key3'
etc etc so instead of creating your array as a comma separated list of key words do it as a pipe separated list and then just push the string into your regex too this is simply an example
Don't SELECT *, only select what you need.
If you want to do complete-text searches, lose the % and add an index
You misspelled column

Mysql search with PHP

I'm using PHP to search a Mysql DB, i'm echoing the query so i can see whats going through, its coming out as this:
select * from `parts` where 'category' like 'at'
However nothing is getting returned. I know there is definitely a column called "category" and a field called "at". If i do %at% it just returns every result!
Essentially i want to get all the records where at is a value in the category column
select * from parts where 'category' like 'at'
This doesn't make any sense - the quotes around category declare it to be a literal value rather than an attribute name.
I know there is definitely a column called "category" and a field called "at".
This is getting confusing. The term 'column' is often in place of 'attribute' (the latter is the correct way to describe the data structure within a relational database). As for 'field' - do you mean an instance of an attribute?
I think you mean your code to do this:
select * from parts where category like '%at%'
(the backticks are optional around database entities - i.e. non-literal values - unless they include spaces). Note that using te like operator without wildcards is messey so if you're looking for the values matching 'at' and not 'cat' or 'attach'....
select * from parts where category='at'
It's not clear from your question which should be literals and which should be field names. Use left apostrophes for field names. So, if you want all records where category field contains literal "at", do:
Change your quotes:
select * from `parts` where `category` like '%at%'
Not sure what do you mean by field called "at" but if it a row value
Try this
select * from `parts` where category='at';
You cannot really compare two fields using like in this way. The second argument to Like is an pattern and interpreted as a regular expression. You can try this:
select * from parts where category like concat('%', at, '%')
It will take the value from the at field, add the % signs then compare the fields.

Categories