MySQL "LIKE" search doesn't work - php

I've imported a .txt database in MySQL through "LOAD DATA INFILE", and everything seemed working, the only problem is that if I search a record on the DB with the following query:
"SELECT * FROM hobby WHERE name LIKE 'Beading'"
it returns 0 rows, while if I use
""SELECT * FROM hobby WHERE name LIKE '%Beading%'"
it returns 1 row, even if exist one record with name=Beading. Does anybody know what could it depend on?

When using SQL LIKE:
You should use a wildcard identifier such as (or not):
'%word' - return results that the value ends with the letters: "word".
'word%' - return results that begin with the letters: "word".
%word% - return results that include the letters: "word" anywhere.
there are some more pattern search combination like:
'abc' LIKE 'abc' true
'abc' LIKE 'a%' true
'abc' LIKE 'b' true
'abc' LIKE 'c' false
If you want an exact match you should use:
"SELECT * FROM hobby WHERE name='Beading'"
But LIKE 'Beading' should also work, so it's probably a spaces issue or case sensitivity problem.
You need to take care of collation case (sensitivity) when you want to make sure your results are complete.
Say your table is UTF...CS and you want to make an insensitive case search you should declare it in your SQL query, for example:
SELECT * FROM hobby WHERE name COLLATE UTF8_GENERAL_CI LIKE 'beading'
try testing different approaches and see what fits your goal best.

the first one doesnt work because Like statment you should use '%search word%'
you should use this one
"SELECT * FROM hobby WHERE name LIKE '% Beading %' or name LIKE '% Beading'
or name LIKE 'Beading %' or name LIKE 'Beading'"

Related

search without hyphen in mysql

Mysql database contains below kind of values :
'AE01-1056 Ricoh Aficio' OR 'Ricoh AE01-1087 (AE01-1069)' etc
AS if am a normal user i will search the product name in simple text like
AE011056 ... but the result is not found.
i hav tried this query:
$q="SELECT * FROM mytable WHERE (p.product_name LIKE '$name%' OR c.category_name LIKE '$name%' OR pm.name LIKE '$name%')";
What change should i make in my query to get the product , because i have tried LIKE operator & it's not working for me.
Use replace function
$q="SELECT * FROM mytable
WHERE (REPLACE(p.product_name,'-','') LIKE '%$name%'
OR REPLACE(c.category_name,'-','') LIKE '%$name%'
OR REPLACE(pm.name ,'-','') LIKE '%$name%')";
I think there are only two ways:
1. Manipulate search string
If you knwo, users are often search for a code and don't use nessesary hyphens, check the searchstring bevor searching if it follows a given format an insert the hypen if it is missing.
2. replace all hyphens in the where-statement
see http://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_replace
Depending on your setup, solution one might be the more performant solution, since you only have to do one instead multiple stringmanipulations.

MySQL select only using first word of variable

I am using php and mySQL. I have a select query that is not working. My code is:
$bookquery = "SELECT * FROM my_books WHERE book_title = '$book' OR book_title_short = '$book' OR book_title_long = '$book' OR book_id = '$book'";
The code searches several title types and returns the desired reference most of the time, except when the name of the book starts with a numeral. Though rare, some of my book titles are in the form "2 Book". In such cases, the query only looks at the "2", assumes it is a "book_id" and returns the second entry in the database, instead of the entry for "2 Book". Something like "3 Book" returns the third entry and so forth. I am confused why the select is acting this way, but more importantly, I do not know how to fix it.
If you have a column in your table with a numeric data type (INT, maybe), then your search strategy is going to work strangely for values of $book that start with numbers. You have discovered this.
The following expression always returns true in SQL. It's not intuitive, but it's true.
99 = '99 Luftballon'
That's because, when you compare an integer to a string, MySQL implicitly does this:
CAST(stringvalue AS INT)
And, a cast of a string beginning with the text of an integer always returns the value of the integer. For example, the value of
CAST('99 Luftballon' AS INT)
is 99. So you'll get book id 99 if you look for that search term.
It's pointless to try to compare an INT column to a text string that doesn't start with an integer, because CAST('blah blah blah' AS INT) always returns zero. To make your search strategy work better, you should consider omitting OR book_id = '$book' from your search query unless you know that the entirety of $book is a number.
As others mention, my PHP allowed both numerical enties and text entries from the browser. My query was then having a hard time with this, interpreting some of my text entries as numbers by truncating the end. Thus, my "2 Book" was being interpreted as the number "2" and then being queried to find the second book in the database. To fix this I just created a simple if statement in PHP so that my queries only looked for text or numbers. Thus, in my case, my solution was:
if(is_numeric($book)){
$bookquery = "SELECT * FROM books WHERE book_id = '$book'";
}else{
$bookquery = "SELECT * FROM books WHERE book_title = '$book' OR book_title_short = '$book' OR book_title_long = '$book'";
}
This is working great and I am on my way coding happily again. Thanks #OllieJones and others for your questions and ideas which helped me see I needed to approach the problem differently.
Not sure if this is the correct answer for you but it seems like you are searching for only exact values in your select. Have you thought of trying a more generic search for your criteria? Such as...
$bookquery = "SELECT * FROM my_books WHERE book_title LIKE '".$book."' OR book_title_short LIKE '".$book."' OR book_title_long LIKE '".$book."' OR book_id LIKE '".$book."'"
If you are doing some kind of searching you might even want to ensure the characters before the search key are found as well like so....
$bookquery = "SELECT * FROM my_books WHERE book_title LIKE '%".$book."' OR book_title_short LIKE '%".$book."' OR book_title_long LIKE '%".$book."' OR book_id LIKE '%".$book."'"
The % is a special char that looks for allows you to search for the chars you want to search for PLUS any characters before this that aren't in the search criteri... for example $book = "any" with a % before hand in the query like so, '%".$book."'"`` would return bothcompanyand also the wordany` by itself.
If you need to you can add a % to the end also like so, `'%".$book."%'"`` and it would do the same for the beginning and end of the search key

MYSQL LIKE categories returning wrong query due to %

I have a CMS with a bunch of different tags and categories. I obviously use each category as a unique ID and save them in the database like so:
cats -> 2,15,115
tags -> 13,33,113
That is a simple example.
I am having problems when I want to show related content by a GET variable $cat to use in my query:
WHERE cats LIKE '%$cat%'
Here is the challenge, if the $cat = '5' , then it returns, 5, 15, 55, 115... and so on. I just need it to match just '5' and nothing else!
I'm sure I am missing something really, really simple.
EDIT:
The find_in_set works really well. However, my other challenge is my $GET variable is sometimes like this: $cat = 150,181
So how can I use the variable $cat to see if there is just one of those matches ? I want to match either 150 OR 181 against the query ?
you can use FIND_IN_SET() since column cats has these values 2,15,115
SELECT * FROM tableName WHERE FIND_IN_SET('5', cats) > 0
MySQL FIND_IN_SET
If you use LIKE with wildcard character '%' you extend your search all values containing '5' in base of you put your %.
%value% (cointaining)
%value (end with value)
value% (start with value)
You can use like as equal, simply not used %, but I advice you to use equal operator (=)

How do I search Full text with partial matches?

I have a table, with not many rows, and neither many columns. I am doing a Full text search on 3 columns.
My code is
$search_input = trim($_GET['s']);
$search = mysql_real_escape_string($search_input);
$search = '+'.str_replace(' ', '* +', $search).'*';
$sql = "SELECT * FROM table WHERE
MATCH(def, pqr, xyz) AGAINST ('$search' IN BOOLEAN MODE)";
$result = mysql_query($sql);
I can correctly search for terms like abcdefgh, which are present as ... abcdefgh ....
But I am receiving empty set with search terms like abc, where in table entry is present something like abc-123, and also terms like abcdefghs. (notice this is plural of above)
Clearly I need to implement partial search, or something like that.
But how do I implement such a search? Any better way to do a entire table search on user input?
Do mention anything I am doing incorrectly.
EDIT : By adding * after each word, now I am able to also search for abcde, but above problems remains.
Do you mean you don't get results for 3 letter combinations? If so, you might be hitting the mysql index length (which is usually set to 3)
More info here - http://dev.mysql.com/doc/refman/5.1/en/fulltext-fine-tuning.html

MySQL LIKE question

I have a script:
$friendnotes = mysql_query("SELECT nid,user,subject,message FROM friendnote
WHERE tousers LIKE '%$userinfo[username]%' ");
And the content in the "tousers" table of the database:
Test
Example
User
That script appears to be working well
However, if there is a user called "Test2", it would also display content that has "Test2" in the database where $userinfo[username] is just "Test"
Is there any way to fix that problem? For example (this is just an example, I don't mind if you give another way) make it so that it searches whole lines?
EDIT: I don't think anyone understands, the "tousers" table contains multiple values (seperated by line) not just one, I want it to search each LINE (or anything that works similiar), not row
The condition
tousers LIKE '%Test%'
means that touser contains "Test" at some point, so it is true for "Test","MyTest","Test3","MyTest3", and so on.
If you want only to match the current user, try
... WHERE tousers = '$userinfo[username]'
EDIT If you really want to store multiple names in one column (separated by newlines), you could use a REGEXP pattern like
WHERE tousers REGEXP '(^|\\n)($userinfo[username])($|\\n)'
Be aware to make sure that $userinfo[username] does not contain any regular-expression-like characters ('$', '^', '|', '(', etc.). Also (as mentioned in the comments above) this solution is suboptimal in terms of security/performance/etc: It would be better to model an 1:n-Relationship between the friendnote table and some friendnotes_user table ...
Ok, so it sounds like the tousers field can contain values like 'stuff test option whatever' and 'foo test2 something blah blah', and you want to match the first but not the second. In that case, you need to include the delimiters around your search term. Assuming the search term will always have a space before and either a space or comma after it, you could do something like:
... WHERE tousers LIKE '%[ ]$userinfo[username][ ,]%'
This will encounter problems, however, if your search term can occur at the beginning of the field (no space character before it) or at the end of the field (no delimiter after it). In that case, you might need to have multiple LIKE clauses.
This will work if you remove the % signs, which are what allow for pattern matching.
$friendnotes = mysql_query("SELECT nid,user,subject,message FROM friendnote
WHERE tousers LIKE '$userinfo[username]' ");
But the consensus seems to be that using equals will be faster. See https://stackoverflow.com/questions/543580/equals-vs-like.
So in that case, change to
$friendnotes = mysql_query("SELECT nid,user,subject,message FROM friendnote
WHERE tousers = '$userinfo[username]' ");
Edit - regarding your edit, that is not a really good design. If a user can have multiple "tousers" (ie a one-to-many relationship), that should be represented as a separate table tousers, where each row represents one "touser" and has a foreign key on the user id to match it with the friendnote table. But if you absolutely can't change your design, you might want to match like this:
WHERE tousers LIKE '%$userinfo[username]\n%' ");
ensuring that there is a line break immediately following the username.
From what I understand, you should just use strict comparison:
where tousers = 'whatever'
That is because tousers like %whatever% matches any row, in which the tousers field has 'whatever' anywhere in its content, so it matches 'whatever', '123whatever', 'whatever321' and '123whatever321'. I hope you get the idea.
So you only want to search for exact name matches? If so, just use an = and remove the % wildcards:
$friendnotes = mysql_query("SELECT nid,user,subject,message FROM friendnote
WHERE tousers = '$userinfo[username]' ");
This is a perfect usage case for the MySQL REGEXP operator.

Categories