PHP SQL Search query matching - php

I have a search page in PHP which uses the following query to fetch content from the database.
SELECT * FROM linkBase WHERE (`title` LIKE '%".$s."%') OR (`descr` LIKE '%".$s."%')
Here is how my DB looks like :
id |title |descr
-----------------------------------------
1 |Hello World |This is a hello world description
2 |PiedPiper |The silicon valley company PiedPiper
3 |StackOverflow |Ask questions on programming
Now, for example, if I run this query with the value of $s = "silicon valley", Then it fetches the row 2. This is fine. But what if the user enters the search term as silicon PiedPiper. It returns no results with the above SQL query. How can I modify the query in such a way that it will return row 2 with the second search term too.
Question summery :
How can I do a search query using PHP and SQL in such a way that a result will be returned even if the the user enters two words which are not placed consequent to each other in the DB

If you need to support an arbitrary order of the words in the search I suggest using the REGEXP MySQL function with a simple "or" regular expression like
SELECT * FROM linkBase WHERE (`title` REGEXP 'silicon|PiedPiper') OR (`descr` REGEXP 'silicon|PiedPiper')
so you can replace the whitespace with PHP and replace them with a pipe symbol (|) and the order of the words don't matter anymore.
This will select all rows that contain at least one of the words, if you need to match all words in the list another regular expression might be necessary.

LIKE '%{".$s."}%' or to be old school INSTR(title, '{'.$s.'}') > 0

Related

PDO search query

PDO, I want to use a search query. I tried to use like query, using % on both front and end of search variable. but it search in between the words.
like if in database there is name Jhon Anderson and if i use search variable using LIKE %erson%, The query will get me the row which contains the above name.
But what i want is query should only search with starting alphabets so i tried the LIKE query with Jhon%, i got the desired result, but using this % in the end only works if search variable matches the starting of first word, but what about the word after the space?
I mean if i try Anderson% or Ander%, The query will not get me the result of this row as Anderson is the second word in the field Jhon Anderson after space.
So my question is how to search in the words after spaces, that if there starting alphabets match the search query.
I don't know if such kind of query exist or not, but i think it might be possible with some looping after using like query with wildcard '%'.$variable.'%' and after getting all the results unset the arrays or rows where search variable do not match with the first alphabet of the result.
Any ideas how to implement such kind of search.
Query right now i am using,
$stmt = $conn->prepare("SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE LOWER(GUEST_FIRST_NAME) LIKE ? OR LOWER(GUEST_NAME) LIKE ?");
$stmt->execute(array('%'.strtolower($searchFilter).'%','%'.strtolower($searchFilter).'%' ));
A bit dirty, but simple solution is to include the space in the search:
WHERE ' ' || Name LIKE '% Anderson%'
You see I added a space in front of Name, so it will also find the word if it is at the beginning of the string.
Alternatively, you can use REGEXP_LIKE, but then it is still a bit awkward, since Oracle doesn't have a word boundary expression in its regex engine. For a solution, see this answer

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.

mysql search database against a query

I'm looking for a way to compare database values against a given query using MySql
(in oppose of searching the query in the db)
I will elaborate:
I have a table that holds comma separated keywords and a result for each block of keywords
for example :
col 1 col 2
Mercedes,BMW,Subaru car
Marlboro,Winston cigarette
today im taking the user query (for example - Marlboroligt)
as you can see if i will search for the value 'Marlboroligt' in the db i will get no results.
for that matter i want to search 'Marlboro' from the db inside the query and return 'cigarette'
Hope my explanation is sufficient and that this is actually possible :-).
Normalization will help you the most. Otherwise, search in comma delimited fields is discussed here:
Select all where field contains string separated by comma
...and to search 'Marlboroligt' instead of 'Marlboro Light', you can try looking into the LEVENSHTEIN function, or maybe the Soundex encoding (which looks like too little bang for too large a buck, but then again, maybe...).
I see the following possible solutions:
setup a keyword-search engine like Sphinx and use it to search keywords in your db
normalize your db - col1 must contain the only keyword
use like patterns
select col2 from mytable where col1 like "%Marlboro%"
like slows down your application and can have substring-related issues.

php mysql search data with multiple keywords

I currently have my query to have LIKE('%keyterm%'). It works fine if my data has one keyboard typed. But what if I want to type in two keywords. Then it will return false.
Example:
keyword : rock climbing
data in mysql: Rock Day Free Climb
This phrase should come out because it has Rock and Climb but it seems like LIKE is not enough?
What else would I need to get that query?
Thanks!
You'll need to split on the whitespace and have a LIKE('%keyterm%') statement for each. See php.net/explode
Return results containing either keyword1 or keyword2:
SELECT * FROM table WHERE data LIKE '%keyword1%' OR data LIKE '%keyword2%';
Return results containing both keyword1 and keyword2:
SELECT * FROM table WHERE data LIKE '%keyword1%' AND data LIKE '%keyword2%';

PHP search function to look in pgsql table

I want to make a search function in my website. I want to search for a string in all fields of my table (about 13 columns). If one row contains a field that matches the string (like operator) I want it to be added to result.
Example
|field 1 | field 2 | field 3|
some string test
test some string
one simple string
Now basically if I search for the string "test" I want to have the first two rows.
Is there a wildcard option for WHERE that I could do something :
SELECT * from my.table WHERE * like '%string%';
There is no such syntax in PostgreSQL (or any other DBMS).
As Spudley pointed out using a query like like '%string%' will be quite slow.
If this is something that is needed very often you should definitely look into PostgreSQL's full text search capabilities.

Categories