MySQL select question: how to do a SELECT with any optional dropdowns? - php

OK, I've done my best to find a thread like this but no luck so far and need some help crafting my SQL query. I'm working on a real estate project and have a form with multiple dropdowns, like so:
<select name="bed" id="bed">
<option value="0">Any</option>
<option value="1">1 Bedroom</option>
<option value="2">2 Bedroom</option>
<option value="3">3 Bedroom</option>
<option value="4">4 Bedroom</option>
<option value="5">5 Bedroom</option>
<option value="6">6 Bedroom</option>
</select>
<select name="bed" id="bed">
<option value="0">Any</option>
<option value="1">1 Bedroom</option>
<option value="2">2 Bedroom</option>
<option value="3">3 Bedroom</option>
<option value="4">4 Bedroom</option>
<option value="5">5 Bedroom</option>
<option value="6">6 Bedroom</option>
</select>
If the user wants to search properties and selects both a 'bed' and a 'bath' number -- as in, 4 bed / 2 bath -- then it's easy:
SELECT * FROM exp_channel_data WHERE field_id_4 = '<?= $search['bed'] ?>' AND field_id_5 = '<?= $search['bath'] ?>
(In which I've captured the POST data in an array.) This works as expected.
But if the user picks only beds -- as in, show me all the properties that have 3 bedrooms however many baths -- and leaves the bath dropdown empty (or 'any'), then I only need a SELECT statement like the above but without the 'AND' in the 'WHERE'.
So my question is, how might I check for the existence of a non-zero amount for the bath dropdown and update the SELECT statement based on the POST array? I suspect it's much easier than I think, I've just been staring too long... Thanks in advance for even pointing me in the right direction.

I would do something like:
$query = "SELECT * FROM exp_channel_data WHERE 1 = 1 ";
if($search['bed']) $query .= "AND field_id_4 = ".$search['bed'].' ';
if($search['bath']) $query .= "AND field_id_5 = ".$search['bath'].' ';
$results = mysql_query($query);

<?php
$conditions = array();
if ($search['bed'] != 0)
$conditions[] = '`field_id_4` = '.$search['bed'];
if ($search['bath'] != 0)
$conditions[] = '`field_id_5` = '.$search['bath'];
$sql = "SELECT * FROM exp_channel_data".(!empty($conditions) ? " WHERE ".implode(' AND ', $conditions) : '');
?>

Here's something you can use and potentially expand in the future. I'm assuming you don't have anything else in that $search[] array - if you do, then you'd want a new array with just the applicable fields in it.
$query = "SELECT * FROM exp_channel_data"
$conditions = array();
$where = '';
foreach($search as $field => $value)
{
if($value != 0)
{
$conditions[] = "$field = $value"
}
}
$where = implode(' AND ', $conditions);
if($where != '')
{
$where = " WHERE $where";
}
$query .= $where;
//now go run your query.
The upside here is that if you have several more items, this works for them too.

Related

How to filter based on two arguments from php, in a SQL database

I have a MySQL database, and the table I need to work with has 9 columns of information. My goal is to be able to filter, based on two arguments. For instance, the table is about students so it has data for first name, last name, id, course they are signed up for, status, occupation age and another 2 fields that are not that important. I need to be able to filter, based on the student's status and/or the course.
So far, I managed to get the php work done, with a form and a select tag, to filter based on status, but I have no idea how to add the second part. The done thing should be able to filter, based on status only, based on course only, or based on the selected status and course. The code looks like this:
if (isset($_POST['filter'])) {
$search_term = mysqli_real_escape_string($conn, $_POST['filter_status']);
$q .= " WHERE status = '$search_term'";
}
echo $q;
<form method="POST" action="index.php">
<select name="filter_status" >
<option value="confirmed">confirmed</option>
<option value="declined">declined</option>
<option value="rejected">rejected</option>
<option value="pending">pending</option>
<option value="unconfirmed">unconfirmed</option>
</select>
<input type="submit" name="filter">
</form>
This works correctly, I have it a second time for the second criteria, but they don't work together.
try to change,
$q .= " WHERE status = '$search_term'";
to
$q .= " WHERE CONCAT_WS(',',status,course) like %'$search_term'%";
you can add as many columns after course.
$filter_status = $_POST['filter_status'];
$course = $_POST['course'];
$where = 'WHERE 1';
$where .= $filter_status ? " AND status = {$filter_status}" : '';
$where .= $course ? " AND course = {$course}" : '';
Did you mean this? when user select course and filter_status use this two conditions, on the other hand use one of conditions which is being selected.
The WHERE 1 will always be TRUE, so it can be followed by AND statements
Use the term AND or OR in your query after WHERE
WHERE status = '$search_term' AND course = '$something'
Thank you all for your input. It helped nudge me in the right direction. The code that ended up doing what I needed is as follows. It's not very elegant, but it does the job well:
$q = "SELECT *
FROM students";
if (isset($_POST['filter'])) {
if ($_POST['filter_status'] == null) {
$search_term2 = mysqli_real_escape_string($conn, $_POST['filter_course']);
$q .= " WHERE course = '$search_term2'";
} elseif ($_POST['filter_course'] == null) {
$search_term = mysqli_real_escape_string($conn, $_POST['filter_status']);
$q .= " WHERE status = '$search_term'";
} else {
$search_term = mysqli_real_escape_string($conn, $_POST['filter_status']);
$search_term2 = mysqli_real_escape_string($conn, $_POST['filter_course']);
$q .= " WHERE status = '$search_term' AND course = '$search_term2'";
}
}
And the form:
<form method="POST" action="index.php">
<select name="filter_status" >
<option value= ""></option>
<option value="confirmed">confirmed</option>
<option value="declined">declined</option>
<option value="rejected">rejected</option>
<option value="pending">pending</option>
<option value="unconfirmed">unconfirmed</option>
</select>
<select name="filter_course">
<option value= ""></option>
<option value="php">php</option>
<option value="java">java</option>
</select>
<input type="submit" name="filter">
</form>

Making Select Boxes Have Database Entry Set As Selected in PHP

How would I go about setting the "selected" attribute to one of these boxes, based on what value is stored in the $genre variable?
i.e. If $genre == "Puzzle" then
<option value=Puzzle>
becomes
<option value=Puzzle selected>
Here is my current code:
<?php
$query = "SELECT * FROM release_dates WHERE id = $id";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
$genre = $row['game_genre'];
?>
<select name=genre>
<option value=Action>Action</option>
<option value=Adventure>Adventure</option>
<option value=Puzzle>Puzzle</option>
<option value=RPG>RPG</option>
<option value=Horror>Horror</option>
<option value=Shooter>Shooter</option>
<option value=Simulator>Simulator</option>
<option value=Sport>Sport</option>
<option value=Strategy>Strategy</option>
</select>
Also, for extra brownie points, how would this apply to select boxes with the "multiple" attribute?
Any help or ideas would be greatly appreciated.
Well, that's pretty simple actually:
<option value=Action <?php $genre == "Action" ? "selected":""?> >Action</option>
Just use a ternary operator (condition) ? true:false to input "selected" if the value is set. Simply duplicate that logic on all the options:
<option value=Action <?php $genre == "Action" ? "selected":""?> >Action</option>
<option value=Adventure <?php $genre == "Adventure" ? "selected":""?> >Adventure</option>
<option value=Puzzle <?php $genre == "Puzzle" ? "selected":""?> >Puzzle</option>
<option value=RPG <?php $genre == "RPG" ? "selected":""?> >RPG</option>
Hope that helps!
You could use a foreach loop to iterate over your options, and each time, perform a check using an if statement to see if it matches:
foreach ($genres as $genre) {
if ($genre === "Puzzle") {
echo '<option value="'.$genre.'" selected>'.$genre.'</option>';
else {
echo '<option value="'.$genre.'">'.$genre.'</option>';
}
}
By the way, you shouldn't be using mysql_* functions anymore as they are unsafe, deprecated, and will be removed from PHP in the future. Take a look at PDO.
<option value="Strategy" <?php if($genre == "Strategy"){ echo 'selected="selected"';} ?> >Strategy</option>
I came up with a version that keeps everything in PHP
<?php
$query = "SELECT * FROM release_dates WHERE id = ". $id;
$result = mysql_query($query);
$row = mysql_fetch_array($result);
// possible options
$genre_options = array(
'Action'
'Adventure'
'Puzzle'
'RPG'
'Horror'
'Shooter'
'Simulator'
'Sport'
'Strategy'
);
// loop over the options, and wrap them in tags
$options = '';
foreach ($genre_options as $genre) {
// check if we have a match
$selected = '';
if ($genre == $row['game_genre']) {
$selected = 'selected="selected"';
}
$options .= '<option value="'. $genre .'" '. $selected .'>'. $genre .'</option>'
}
echo '
<select name=genre>
'. $options .'
</select>
';
?>
What this does is create an array of possible genre's, loop over them, and see if any of them match the genre that was returned from the query. If thats the case it will add the selected="selected" attribute.
Unfortunately I'll be missing out on the "brownie points", because I'm not able to help you with the multi-select.
Let me know if this helps!
EDIT: I also noted that in your query you where passing the $id variable as a string. Fixed that in the query in my example.
Instead of defining your genres using plain HTML, create an array with all your genres.
To do so:
$genres = array(
"Action",
"Adventure",
"Puzzle",
"RPG",
"Horror",
"Shooter",
"Simulator",
"Sport",
"Strategy"
);
foreach($genres as $currentGenre) {
echo "<option value="'.$currentGenre.'" '.($currentGenre == $genre ? "selected" : "").'>'.$currentGenre.'</option>';
}
What this does, is loop over all your genres and create a single <option> for each of them. If the $currentGenre (so one of the genres from the array $genres) matches $genre (which you pulled from MySQL), it selects that option using a inline if-statement.

Searching using PDO

So I'm trying to execute a search using PDO. I have this search set up:
echo "<form action = 'user.php?search=yes' method = 'post' id='searchform'>
<a href='user.php?newuser=yes'>Add New User</a> || Search By
<select name = 'paramet' form = 'searchform'>
<option value = 'userID'>User ID</option>
<option value = 'firstname'>First Name</option>
<option value = 'lastname'>Last Name</option>
<option value = 'email'>E-Mail</option>
<option value = 'mobileno'>Mobile Number</option>
<option value = 'homeno'>Home Number</option>
</select>
<select name = 'howso' form = 'searchform'>
<option value = 'contains'>which contains</option>
<option value = 'equalto'>which is equal to</option>
</select>
<input type = 'text' name='criteria' required>
<input type = 'submit' value='Search'>
</form>
And then this handling the query:
{
$param = $_POST['paramet'];
$how = $_POST['howso'];
$crite = $_POST['criteria'];
if($how == 'contains')
{
$query = $hsdbc->prepare("SELECT * FROM user WHERE :param LIKE :crite");
$query->bindParam(':param', $param);
$query->bindValue(':crite', '%' . $crite . '%');
$query->execute();
}
else{
$query = $hsdbc->prepare("SELECT * FROM user WHERE :param = :crite");
$query->bindParam(':param', $param);
$query->bindParam(':crite', $crite);
$query->execute();
}
I'm getting no-where near the correct results. Any help?
You can't bind column names. The best you can do is add the name to a white list array or something and insert it manually.
if(in_array($param, $good_params_array)) {
$query = $hsdbc->prepare("SELECT * FROM user WHERE $param LIKE :crite");
$query->bindValue(':crite', '%' . $crite . '%');
$query->execute();
}
I've seen people query the DB for the table description to get the columns to see if the column name is listed, but that requires an addition DB request. Also, you might want to limit the fields they can search against

Select all option values php mysql

I'm trying to select all values from my MySQL database. Options a, b, and c work fine but I'm not sure of the syntax to select all three.
<option value="1">a</option>
<option value="2">b</option>
<option value="3">c</option>
<option value="1,2,3">All</option>
I think you want to use the select to fetch a item or all items if I understand your question correctly and by seeing your 'all' option's value.
If so then change your select option's value for all to <option value="all">all items</option>.
Then change your PHP file (where you posting to with the form) to this:
// is the all option send?
if($_POST['your_select'] === 'all') {
//query to get all the items (SELECT * FROM table)
} else {
// query with the post value as the id (SELECT * FROM table WHERE id = $_POST['your_select'])
}
i think you want multiple="multiple" it will allow you to select multiple
<select name="modules[]" multiple="multiple">
<option value="1">a</option>
<option value="2">b</option>
<option value="3">c</option>
<option value="1,2,3">All</option>
</select>
now you will get array of selected option which you can get by either GET or POST
to select all on selecting last you can use jquery like
$('option').click(function(){
if($(this).val() =='1,2,3'){
$("option").attr("selected", "selected");
}
})
Try this
<form action="my_page.php" method="post">
<select name="my_select">
<option value="1">a</option>
<option value="2">b</option>
<option value="3">c</option>
<option value="1,2,3">All</option>
</select>
<input type="submit" name="submit" value="Submit" />
</form>
<?php
# in my_page.php page
# put submitted value of the select tag in an array
# (submitted value in this case equals "1", "2", "3" or "1,2,3")
$values = explode(",", $_POST["my_select"]);
# get number of values in the array
$num_of_values = count($values);
# escape all values before using them in your sql statement
foreach ($values as $key => $val) {
$values["$key"] = mysql_real_escape_string($val);
}
# if we have more than 1 value in the array
if (count($values) > 1) {
$sql = "SELECT * FROM table_name WHERE "; # note the space after "WHERE" keyword
for ($i = 0; $i < $num_of_values; $i++) {
# this "if" statement is for removing the "OR" keyword from the sql statement
# when we reach the last value of the array
if ($i != $num_of_values - 1) {
$sql .= "column_name = '{$values[$i]}' OR "; # note the space after "OR"
} else { #if we reached the last value of the array then remove the "OR" keyword
$sql .= "column_name = '{$values[$i]}'";
}
}
# execute your query
$result = mysql_query($sql);
} else { # if we have only one value in the array
$result = mysql_query("SELECT * FROM table_name WHERE column_name = '{$values[0]}'");
}
?>

Multiple Dropdowns Dynamic Query AJAX PHP MySQL

I am currently creating a multiple dropdown query where the user can query by (3) factors for returning results, my issue is how can I do this in an efficient manner so I am not obscurely writing multiple possible MySQL Queries.
<select name="class">
<OPTION VALUE='any'>Choose Class
<option value="a">Block A</option>
<option value="b">Block B</option>
<option value="c">Block C</option>
</select>
<select name="category">
<OPTION VALUE='any'>Choose Type
<option value="math">Math</option>
<option value="science">Science</option>
<option value="history">History</option>
</select>
How can I successfully create a MySQL query that will correctly select the right parameters in the case that a variable is missing. In example, if they choose to do the first dropdown and only search for the "class" and not choose the second dropdown. I want to be able to do the first query, the second query or both of them. I have the PHP, Ajax written, I'm just stumped as to the correct structure of the MySQL query.
Put your "WHERE" clause conditions in one array. I would do like this:
// filter out invalid values is important
$valid_class = array('a', 'b', 'c');
$valid_category = array('math', 'science', 'history');
// initialize array for WHERE clause conditions
$where = array('TRUE');
if (in_array($_POST['class'], $valid_class))
{
$where[] = 'class = "' . $_POST['class'] . '"';
}
if (in_array($_POST['category'], $valid_category))
{
$where[] = 'category = "' . $_POST['category'] . '"';
}
// use the array with the "implode" function to join its parts
$sql = 'SELECT * FROM table WHERE ' . implode(' AND ', $where);
You may want to initialize the $where array with something more interesting than "TRUE" (which is there in case the user does not filter by class neither category, because we don't want an empty $where array reaching the last line). For example:
$where = array();
$where[] = 'name = "' . mysql_real_escape_string($_POST['name']) . '"';
<select name="class">
<OPTION VALUE="">Choose Class
<option value="a">Block A</option>
<option value="b">Block B</option>
<option value="c">Block C</option>
</select>
<select name="category">
<OPTION VALUE="">Choose Type
<option value="math">Math</option>
<option value="science">Science</option>
<option value="history">History</option>
</select>
set the column of the table on ur MySQL to allow null
so when user select " <OPTION VALUE="">Choose Type" or "<OPTION VALUE="">Choose Class", pass Null into the column
Break the query in pieces and use it conditionally
suppose: $class is for class select box and $category is for category select box
$selectquery = "select * from tablename ";
if($class != "" && $category == ""){
$selectquery .= "WHERE class='".$class."'";
}elseif($class == "" && $category != ""){
$selectquery .= "WHERE category ='".$category."'";
}elseif($class != "" && $category != ""){
$selectquery .= "WHERE category ='".$category."' AND class='".$class."'";
}

Categories