How can I use a WHERE MySQL clause in a statement which can fetch me all the records? I am settings the WHERE condition conditionally. Like...
if (this) {
$mycondition=1;
} elseif (that {
$mycondition=????
}
'SELECT * FROM table WHERE category='.$mycondition
What should be the value of ???? so that when I pass it to the sql statement it fetches me all the records. I was thinking that WHERE category='*' might work but it does not.
You need to build your WHERE condition piece by piece :
start with an empty array
add some conditions depending on search form input (like add "category=1" or "name like ...")
implode( " AND ", $array ) will stick the conditions together
concatenate this in your SQL
if there is no condition, don't put a where clause
The best answer is not to have a WHERE clause at all, as suggested as part of peufeu's answer if you don't have a condition to be met:
SELECT * FROM table;
Is perfectly valid.
However, if you are in a situation where you must have a WHERE clause (or where it's drastically easier to have one), do as Nanne suggests, and put an "always true" condition as your first clause, so something like:
$query = 'SELECT * FROM TABLE WHERE true';
if (this) {
$query = $query . ' AND column=this';
}
You could just use this
if(this){
$mycondition=" category=1";
}elseif(that{
$mycondition= " 1"; //1 = 'true'. You could also use "1=1
}
'SELECT * FROM table WHERE '.$mycondition
Related
Does anyone know how to get a mysql query to ignore a certain where condition if the PHP value is empty. I am trying to create an advance search engine with many strict where conditions to filter search, but would like the SQL to ignore some of the where causes if the PHP value is empty.
For example:
$condition_1 = ' ';
$condition_2 = 'Random';
mysql_query("SELECT something FROM table WHERE row_1='$condition_1' && row_2='$condition_2'")
There will be 15 where causes in the query, so anything that involves making multiple queries for different combination of searches is not doable.
$condition_1 is empty and will show results to only those with no value in row_1 , but I just want to have the query ignore the row_1 condition when the PHP value, $condition_1, is empty. How would I do this?
You can construct your where condition dynamically, note that this also works if both conditions are empty
$sql = "SELECT something FROM table where 1 ";
if(trim($condition_1) != '')
$sql .= " AND row_1='$condition_1'";
if(trim($condition_2) != '')
$sql .= " AND row_2='$condition_2'";
mysql_query($sql);
I have a variable that is a filter for my query:
$filterString.=" AND venue = ".$venue;
And I want this variable (when called) to add the AND filter statement to my query.
My query is as follows (with the failed attempt):
mysql_query("SELECT * FROM event
WHERE city = '$city' " . $filterString . "
ORDER BY date ASC");
I think the venue needs to be surrounded by single quotes:
$filterString.=" AND venue = '".$venue.".";
However, it is better to use parameterized queries, instead of embedding queries directly in the SQL string.
You could use:
$filterString .= !empty($venue) ? " AND venue = '$venue'" : '';
Substitute whatever test you want at the start, the idea is to return a blank string if $venue doesn't apply to the filter.
To answer your other comment question:
WHERE 1
is a valid condition that works like Anything
I'm having a little trouble with my MYSQL query
I have a DB full of products and I have a dropdown menu which lets a user select what time of day they'd like to get get results for :-
Dropdown
Breakfast
Lunch
Evening
Anytime
At the moment my statement is
SELECT * from DEALS WHERE timeofday='post data from form';
Now this works fine, but with the option for 'Anytime' I'd like the query to be able to search for results of all/any of the above.
I was thinking of perhaps doing an IF statement which fires off 2 separate queries, one which says if the $_POST['timeofday'] == 'Anytime' then fire off
SELECT * from DEALS where timeofday='Breakfast'
OR timeofday='Lunch' OR timeofday='Evening';
otherwise just do the normal query, although wondered if it was possible to do this in just one statement.
Kind regards
$query = 'SELECT * from DEALS';
if ($_POST['timeofday'] != 'Anytime') {
$query .= ' WHERE timeofday="' . $_POST['timeofday'] . '"';
}
As DCoder mentioned, this approach is vulnerable to sql injection... You should check/sanitize the input or use prepared statements. In this case where there is a predefined set of values you can:
$knownTimesOfDay = array('Breakfast', 'Lunch', 'Evening', 'Anytime');
if (!in_array($_POST['timeofday'])) {
die('Unsuppotred time of day... Did it really come from the form?');
}
$query = 'SELECT * from DEALS';
if ($_POST['timeofday'] != 'Anytime') {
$query .= ' WHERE timeofday="' . $_POST['timeofday'] . '"';
}
Don't think it can be done in one statement.
You are going to have to use an if statement anyhow.
if these are the only 3 possible values for timeofday,then you can have an if in the php script like this:
if($_POST['timeofday'] != 'Anytime' )
sql .= "where timeofday='".$_POST['timeofday']."'";
This could turn out to be negative depending on the items you have in the table, but you could use:
SELECT * from DEALS where timeofday LIKE '%{$post_data}%'
It would return all the results from timeofday if $post_data was an empty string.
I'd like to create a query in MySQL that has an optional value. When the value is specified the query is filtered by that value, when the value is not all rows are returned. Here's the idea:
public function doQuery($item = 'ANY_VALUE') {
$query = "SELECT * FROM table WHERE item = ?";
db->fetchAll($query,array($item))
...
}
doQuery(); // Returns everything
doQuery($item='item1'); // Returns only rows where item = 'item1'
Is there an easy way to do this without creating two query strings depending on the value of $item?
As far as I know, no such "any" placeholder exists.
If you can use LIKE, you could do
SELECT * FROM table WHERE item LIKE '%'
if you can append a condition, you could nullify the item clause like this:
SELECT * FROM table WHERE item = ? OR 1=1
(won't work in your example though, because you are passing "item" as a parameter)
That's all the options I can see - it's probably easiest to work with two queries, removing the WHERE clause altogether in the second one.
This would probably work, but I*m not sure whether it's a good idea from a database point of view.
public function doQuery($item = 'ANY_VALUE') {
$query = "SELECT * FROM table WHERE item = ? OR 1 = ?";
db->fetchAll($query,array($item, ($item == 'ANY_VALUE' ? 1 : 0))
...
}
Better way to do this is first generate sql query from the parameter you need to bother on, and then execute.
function doQuery($params) {
$query = 'SELECT * FROM mytable ';
if (is_array($params) // or whatever your condition ) {
$query .= 'WHERE item = ' . $params[0];
}
$query .= ' ;';
// execute generated query
execute($query);
}
You cannot get distinct results without giving distinct query strings.
Using $q = "... WHERE item = '$item'" you DO create distinct query strings depending on the value of $item, so it is not that different from using
$q = "..." . ($item=='ANY_VALUE' ? something : s_th_else);.
That said I see two or three options:
use function doQuery($item = "%") { $query = "SELECT ... WHERE item LIKE '$item'"; ...}
But then callers to that function must know that they must escape a '%' or '_' character properly if they want to search for an item having this character literally (e.g. for item = "5% alcoholic solution", giving this as argument would also find "50-50 sunflower and olive oil non alcoholic solution".
use function doQuery($item = NULL) { $query = "SELECT ..."; if ($item !== NULL) $query .= " WHERE item = '$item' "; ...} (where I use NULL to allow any other string or numerical value as a valid "non-empty" argument; in case you also want to allow to search for NULL (without quotes) you must choose another "impossible" default value, e.g., [], and you must anyway use a distinct query without the single quotes which however are very important in the general case), or even:
use function doQuery($item = NULL) { if($item === NULL) $query = "SELECT ..."; else $query = "SELECT ... WHERE item = '$item' "; ...}, which is more to type but probably faster since it will avoid an additional string manipulation (concatenation of the first and second part).
I think the 2nd & 3rd options are better than the first one. You should explain why you want to avoid these better solutions.
PS: always take care of not forgetting the quotes in the SQL, and even to properly escape any special characters (quotes, ...) in arguments which can depend on user input, as to avoid SQL injections. You may be keen on finding shortest possible solutions (as I am), but neglecting such aspects is a no-no: it's not a valid solution, so it's not the shortest solution!
Is there any way to check if a column is "anything"? The reason is that i have a searchfunction that get's an ID from the URL, and then it passes it through the sql algorithm and shows the result. But if that URL "function" (?) isn't filled in, it just searches for:
...AND column=''...
and that doesn't return any results at all. I've tried using a "%", but that doesn't do anything.
Any ideas?
Here's the query:
mysql_query("SELECT * FROM filer
WHERE real_name LIKE '%$searchString%'
AND public='1' AND ikon='$tab'
OR filinfo LIKE '%$searchString%'
AND public='1'
AND ikon='$tab'
ORDER BY rank DESC, kommentarer DESC");
The problem is "ikon=''"...
and ikon like '%' would check for the column containing "anything". Note that like can also be used for comparing to literal strings with no wildcards, so, if you change that portion of SQL to use like then you could pre-set the variable to '%' and be all set.
However, as someone else mentioned below, beware of SQL injection attacks. I always strongly suggest that people use mysqli and prepared queries instead of relying on mysql_real_escape_string().
You can dynamically create your query, e.g.:
$query = "SELECT * FROM table WHERE foo='bar'";
if(isset($_GET['id'])) {
$query .= " AND column='" . mysql_real_escape_string($_GET['id']) . "'";
}
Update: Updated code to be closer to the OP's question.
Try using this:
AND ('$tab' = '' OR ikon = '$tab')
If the empty string is given then the condition will always succeed.
Alternatively, from PHP you could build two different queries depending on whether $id is empty or not.
Run your query if search string is provided by wrapping it in if-else condition:
$id = (int) $_GET['id'];
if ($id)
{
// run query
}
else
{
// echo oops
}
There is noway to check if a column is "anything"
The way to include all values into query result is exclude this field from the query.
But you can always build a query dynamically.
Just a small example:
$w=array();
if (!empty($_GET['rooms'])) $w[]="rooms='".mysql_real_escape_string($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mysql_real_escape_string($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mysql_real_escape_string($_GET['max_price'])."'";
if (count($w)) $where="WHERE ".implode(' AND ',$w); else $where='';
$query="select * from table $where";
For your query it's very easy:
$ikon="";
if ($id) $ikon = "AND ikon='$tab'";
mysql_query("SELECT * FROM filer
WHERE (real_name LIKE '%$searchString%'
OR filinfo LIKE '%$searchString%')
AND public='1'
$ikon
ORDER BY rank DESC, kommentarer DESC");
I hope you have all your strings already escaped
I take it that you are adding the values in from variables. The variable is coming and you need to do something with it - too late to hardcode a 'OR 1 = 1' section in there. You need to understand that LIKE isn't what it sounds like (partial matching only) - it does exact matches too. There is no need for 'field = anything' as:
{field LIKE '%'} will give you everything
{field LIKE 'specific_value'} will ONLY give you that value - it is not partial matching like it sounds like it would be.
Using 'specific_value%' or '%specific_value' will start doing partial matching. Therefore LIKE should do all you need for when you have a variable incoming that may be a '%' to get everything or a specific value that you want to match exactly. This is how search filtering behaviour would usually happen I expect.