PDO search query - php

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

Related

PHP How to check if a String is contained in a text from the database using php

I'm creating a paraphrasing system, where a user inputs text and the system paraphrases for them.
My database looks like this:
KeyWord: dainty
Synonyms1: choice; delicious; tasty; juicy; luscious; palatable; savoury
Synonyms2: ethereal; beautiful; fragile; charming; petite; frail; elegant
where Keyword (varchar), Synonym1 (text), and Synomy2 (text) are database columns. The example above is one row of a database with 3 fields and their values.
This how it works if the system finds, for example, a word like tasty, it can be replaced by any of the words separated by a semicolon from either Synomyn1 or Synonym2 or the keyword because they are all synonyms.
Let me explain how the word search is working. The system first searches for the word in the Keyword column, if the word is not found, I go further and search for a word in the Synmon1 column and so on.
My Problem is checking the user's specific word in the Synonym1 or Synonym2 columns. When I use the LIKE clause, the generic way of searching from the database, the system is not searching for a full name, instead, it's searching for characters. For example, let's assume the writer's text is: "Benson has an ice cube", the system is assuming the ice was found in the choice. I don't want that, I want to search for a full word.
If anyone has understood me, please help to solve this.
If I understand your question, you want to search for ice in columns Synonyms1 and Synonyms2 but make sure you do not inadvertently match a word such as choice.
If you have ever read or heard anything on the subject of database normalization you would realize that your database does not even meet the requirements for 1NF (first normal form) becuase it has columns that consist of repeating values, which, as you have found out, makes searching inefficient and difficult. But let's move on:
A synonym column might just contain one word, so it might look like:
ethereal
Or:
ethereal; beautiful; fragile; charming; petite; frail; elegant
Thus the word you are looking for might be:
the entire column value
preceded by nothing and followed by a ;
preceded by a space and followed by a ;
preceded by a space and followed by nothing
So if your version of MySQL does not support regular expressions, then if you are looking for example the word ice in column Synonyms2, the WHERE clause should be:
WHERE (
Synonyms2 = 'ice'
OR
Synonyms2 like 'ice;%'
OR
Synonyms2 like '% ice;%'
OR
Synonyms2 like '% ice'
)
If you are running SQL 8+, then:
WHERE regexp_like(Synonyms2, '( |^)ice(;|$)')
This states that ice must be preceded by either a space or start of string and followd by either a ; or end of string.

How to implement Full Text search in InnoDB?

I have a query,
e.g.
name column have "Rodrigue Dattatray Desilva".
I want to write a query in such a way that,
If I search for 'gtl' and match anywhere in string it should show the result.
I know in PHP I can apply the patch like '%g%t%l%'.
But I want to know MySql way.
Note: I can search for anything, I am just giving above an example.
EDIT:
create table Test(id integer, title varchar(100));
insert into Test(id, title) values(1, "Rodrigue Dattatray Desilva");
select * from Test where title like '%g%t%l%';
Consider the above case. Where "gtl" is string I am trying to search in the title but search string can be anything.
gtl is string where it exists in the current title but not in sequence.
The easy answer is that you need an extra wildcard:
select * from Test where title like '%g%t%l%';
The query you posted does not have a wild card after the 'l', so would only match if the phrase ended with 'l'.
The more complicated answer is that you can also use regular expressions, which give you more power over the search.
The even more complicated answer is that performance of these string matching queries tends to be poor - the wild cards mean that indexes are usually ineffective. If you have a large number of rows in your table, full-text searching is much faster.
You can do the same in Mysql too.
You can use the keyword like in MySql.
% - The percent sign represents zero, one, or multiple characters
_ - The underscore represents a single character

PHP SQL Search query matching

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

Eclipse: Find query strings spread in multiple line

Say a file opened in Eclipse has the following string
$stmt = "select addr from
student
where id=123";
$stmtA = "alter table tablename";
$stmtB = " delete from student
where school=ABC";
$var1 = "This is not a query.
Just a string";
I need to find all query statements that effect student table and school column. Searching with :
(?s)"(.*?)"
gives me all the strings that are quoted and spread over multiple lines. Now how do I enhance the above regex to filter the result so that it ensures that result has
1) select or alter or insert or delete keywords of MySQL,
and
2) student and school keywords.
I think with above two conditions satisfied I will be able to extract strings that hit student table and school column. Any help?
(?s)".*?(?:select|alter|insert|delete).*?(?:student|school).*?"
Though using [^"]*? instead of .*? would maybe be better.
Edit:
Let's switch to lookaheads as they are quite the cool tool when ensuring some conditions (as string length, having a special char or smthg):
(?s)".*?(?:select|alter|insert|delete)(?=[^"]*?student)(?=[^"]*?school).*?"
Ok if you're not interested in regex, you can stop here, else, as an example of lookaheads (note: this is slower):
(?s)"(?=[^"]*?(?:select|alter|insert|delete)(?=[^"]*?student)(?=[^"]*?school).*?"
If you have access to atomic groups, it's always better to do this (atomic grouping):
(?>select|alter|insert|delete)
as if one word fails to match after the 1st letter, it skips the rest (they all have a different first letter).
Finally, I guess you could use if/then/else:
(?s)".*?(?:select|alter|insert|delete).*?(?:(student)|school)(?(1).*?school|.*?student).*?"
Or something similar.

PHP, Database: Preserving and searching strings with whitespace

I have the following scenario:
I am storing user input that MAY contain whitespace. The problem is, when I do a SELECT from the database (MySql), it does not find a match. If I strip the whitespace, the search on db works, but the strings are all messy looking if I store them this way.
How can I properly store strings (with whitespace) in the database AND correctly do SELECT statements that will find those stored strings??
Thanks for the help.
UPDATE:
Here is what I am working with now:
$filename = "This is a string with white space";
//being stored in the db like this
$trim_string = preg_replace("/\s+/", "", $filename);
//search db as Thisisastringwithwhitespace
Still finds no match though?
If the user would know the entire string, I would go with Blake suggestion of using TRIM() in the Mysql query, if you want the partial search, and want it fast, I would create a secondary table with the words and another one for the position where appears in the strings, something like this :
Word( id, string )
WordInString( id, source_string_id, word_id, position )
The search would be in 2 steps :
1. get the words ids
2. get from WordInString the top list with greater number of Words hits, and show the options to the end user.
Hope it helps !

Categories