I tried to get results from my database using SQL but my results do not agree with what i am using as input. I always gets results from those who contains both integers and characters. For example, if i search for "liu" i get a result of "2LK020". I neither cant search with integers and get a correct result... I use:
$result = queryDatabase(
"SELECT course_tag, course_name FROM course WHERE course_tag OR course_name LIKE ?",
array(1 => '%' .$parameters[0]. '%')
is there a problem using "%"? or why do i get this weird answers?
Read this: http://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html
You're doing the equivalent of
WHERE course_tag OR (course_name LIKE ?)
which comes to
WHERE true/false OR true/false
As long as course_tag isn't an empty string or a null or other "falsey" value, it'll pretty much always evaluate to a true value, and make the entire WHERE clause evaluate to true.
You can't test multiple fields against a single LIKE value. That simply doesn't work. You need to test each one individually:
WHERE (course_tag LIKE ?) OR (course_name LIKE ?)
However, since you're doing a %...% double-wild card search, you could optimize a bit with
WHERE CONCAT(course_tag, course_name) LIKE ?
Related
For a search query I have the following:
DB::whereRaw('column = ?', 'foo')->orWhereRaw('column IS NULL')->get();
Adding the orWhereRaw statement gives me less results than only the whereRaw. Somehow it seems to ignore the first when adding the other. It is included in the SQL statement. Is there another way to compare for a string and null value?
I have also tried the following, as suggested below:
return self::select('id')
->where('current_state', 'unavailable')
->orWhereNull('current_state')
->get();
If I change the order (the whereNull first and the where second) this also gives me different results. It appears as if the inclusive query doesn't function correctly in correspondence with the where clause. If I use to regular where clauses I don't experience any issues.
Running SELECT * FROM events WHERE current_state='unavailable' OR current_state IS NULL; does produce the correct result for me.
Don't use whereRaw to check for null. You can use this instead:
->orWhereNull('column')
The proper way to do the first where, unless you're doing something extra such as a mysql function, is just to pass the column along like this:
where('column', '=', 'foo')
You can actually eliminate the equals, since it defaults to that. So your query would be:
DB::table('table')->where('column', 'foo')->orWhereNull('column')->get();
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 query String contains
Hello, I am trying to make an mysql query that looks for a column value that contains a string from a master string I set. So if my master string is '1234567', I would like it to return any results with column values that have '1','2', etc... The above link was as close as to what I can find but I need it comparing in the opposite direction.
eg.:
WHERE '%{$needle}%' LIKE `column`
You are a little vague about where the various values are being stored (your text uses terms like "master string" but the sample code uses different names).
You can do what you want using regexp. Here is an example:
select 'abcd6efg' regexp concat('.*[', '1234567', '].*')
To be honest, regex is different from like in one important respect. regex returns true if any part of the left string matches, whereas for like the entire string has to match. So, the following also works:
select 'abcd6efg' regexp concat('[', '1234567', ']')
I like to put the explicit wildcards in to avoid mistakes when switching between the two.
You can look up the documentation for regular expressions here.
How about
WHERE ? LIKE CONCAT('%', `column`, '%')
where ? is a placeholder having a bound parameter with your master value (1234567) because you are using the PDO or MySQLi extension, right?
You're most certainly not using the deprecated MySQL extension, surely.
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 (=)
I want to let users filter through results.
For this I have several dropdown lists that, by default, are set to 'All'. Values from those fields are sent to php via the POST method, and then I proceed as such:
if ($variable == "All") {
$variable = '%';
}
Then in the PDO statement, the WHERE clause goes as such:
WHERE field LIKE :variable
After that I pass the variable through an array
I get a Division by zero error which is weird because when I hard code the SQL query with
field LIKE '%'
It is all fine...
Thanks for your help, much appreciated since I have been trying out many options to solve this!
Instead of adding lots of useless WHERE conditions like
field1 LIKE :value1 OR field2 LIKE :value2 OR field3 LIKE :value3
generating a query like
field1 LIKE '%' OR field2 LIKE '%' OR field3 LIKE '%actual filter%'
that only result in a longer execution time of your query you should write conditionals that add the filter only when set.
The division by zero error was in fact coming from the fact that my SQL query contained a CONCAT(name,'%') which works for SQL but is not well interpreted by php.
Instead, CONCAT(name, "%") works just fine...
Rookie mistake!