SQL query implementing AND functionality with PHP array - php

I am using PHP with MySql. I need a query which should fetch me results according to my requirements.
I have a table property_features_table which has properties with some features.
In the front end I have a search functionality. When a user selects multiple features suppose
balcony,wifi,2-bedroom etc., He should be shown with properties having ALL the features he selected.
But when I use the following code, I am getting results (properties) which has atleast one of the features.
$featuresString = implode("','",$features);
$featuresString = "'".$featuresString."'";
$query = " SELECT * FROM property_features_tbl WHERE property_features_tbl.feature_id in (".$featuresString.")";
$features is an array which contains user selected features.
I want to display properties which has all the features selected by the user. Help me in writing the query.

Assuming you just want the property ids, then something like this:-
<?php
$featuresString = implode("','",$features);
$featuresString = "'".$featuresString."'";
$feature_count = count($features);
$query = " SELECT property_id, COUNT(*) AS feature_count
FROM property_features_tbl
WHERE property_features_tbl.feature_id in (".$featuresString.")
GROUP BY property_id
HAVING feature_count = $feature_count";
?>

Related

MySQL return rows where column contains categories defined by array (and add weight to the results)

In my app, the user can type in an indefinite amount of categories to search by. Once the user hits submit, I am using AJAX to call my PHP script to query my DB and return the results that match what the user defined for the categories.
My category column is separated as so for each row: "blue,red,yellow,green" etc.
I have two questions:
How can I pass an array to MySQL (like so: [blue,yellow,green]) and then search for each term in the categories column? If at-least one category is found, it should return that row.
Can MySQL add weight to a row that has more of the categories that the user typed in, therefor putting it further to the top of the returned results? If MySQL cannot do this, what would be the best way to do this with PHP?
Thanks for taking the time and looking at my issue.
For the part 1 you can use the function below:
<?php
function createquery($dataarray){
$query="select * from table where ";
$loop=1;
foreach($dataarray as $data)
{
$query.="col='$data'";
if(count($dataarray)<$loop-1){
$query.=' or ';
}
$loop++;
}
return $query;
}
?>
This will return the long query.
use this some like this:
mysql_query("select * from table where category in (".implode($yourarray,',').")");
1)
Arrays are not passed to a MySQL database. What's past is a query which is a string that tells the database what action you want to preform. An example would be: SELECT * FROM myTable WHERE id = 1.
Since you are trying to use the values inside your array to search in the database, you could preform a foreach loop to create a valid SQL command with all those columns in PHP, and then send that command / query to the database. For example:
$array = array('blue', 'red', 'yellow', 'green');
$sql = "SELECT ";
foreach ($array as $value)
{
$sql .= $value.", ";
}
$sql .= " FROM myTable WHERE id = 1";
IMPORTANT! It is highly recommended to used prepared statements and binding your parameters in order not to get hacked with sql injection!
2)
You are able to order the results you obtained in whichever way you like. An example of ordering your results would be as follows:
SELECT * FROM myTable WHERE SALARY > 2000 ORDER BY column1, column2 DESC

Left join MySql/PHP

Whilst populating a table based on ids and labels from different tables, it appeared apparent there must potentially be a better way of achieving the same result with less code and a more direct approach using LEFT JOIN but i am puzzled after trying to work out if its actually capable of achieving the desired result.
Am i correct in thinking a LEFT JOIN is usable in this instance?
Referencing two tables against one another where one lists id's related to another table and that other table has the titles allocated for each reference?
I know full well that if theres independent information for each row LEFT JOIN is suitable, but where theres in this case only several ids to reference for many rows, i just am not clicking with how i could get it to work...
The current way i am achieving my desired result in PHP/MySQL
$itemid = $row['item_id'];
$secid = mysql_query(" SELECT * FROM item_groups WHERE item_id='$itemid' ");
while ($secidrow = mysql_fetch_assoc($secid)) {
//echo $secidrow["section_id"]; //testing
$id = $secidrow["section_id"];
$secnameget = mysql_query(" SELECT * FROM items_section_list WHERE item_sec_id='$id' ");
while ($secname = mysql_fetch_assoc($secnameget)) {
echo $secname["section_name"];
}
}
Example of the data
Item groups
:drink
:food
:shelf
Item List
itemId, groupId
Group List
groupId, groupTitle
The idea so outputting data to a table instead of outputting "Item & Id Number, in place of the ID Number the title actually appears.
I have achieved the desired result but i am always interested in seeking better ways to achieve the desired result.
If I've deciphered your code properly, you should be able to use the following query to get both values at the same time.
$itemid = $row['item_id'];
$secid = mysql_query("
SELECT *
FROM item_groups
LEFT JOIN items_section_list
ON items_section_list.item_sec_id = item_groups.section_id
WHERE item_id='$itemid'
");
while ($secidrow = mysql_fetch_assoc($secid)) {
//$id = $secidrow["section_id"];
echo $secidrow["section_name"];
}

Arrays display order

So this script works like this. It takes the tags you have chosen as your interests and compares it with the other users tags. This script below gives me the output of how many tags me and the other person have common.
$get_userinfo = mysql_query("SELECT * FROM users") or die(mysql_error());
while($userinfo = mysql_fetch_array($get_userinfo)) {
$usertags = $userinfo['tags'];
$tagsdata = explode(" ", $usertags);
$interestsdata = explode(" ", $interests);
$result = array_intersect($interestsdata, $tagsdata);
echo "Count under this belongs to ".$userinfo['name']."";
echo count($result);
echo "<br />";
}
Now, I want first, this script also displays me in the list so I see how many tags I have common with myself and I want to remove myself. And second, how do I list it so the person with highest number (most tags common) get displayed at the top and descending.
Add a condition to exclude yourself from your own query:
SELECT * FROM users WHERE user_id != [your user id]
To order by the number of tags, you need to issue an aggregate function in your SQL statement to group results by the tag and user. Without seeing your table structure I can only offer a very generalized statement
SELECT username, tag, count(tag) FROM users JOIN tags ON x = y WHERE user_id != [your user id] GROUP BY user_id, tag_id ORDER BY count(tag) DESC
Another option is to collect your data, and sort through it with PHP after you already know how many tags each user has in common. See http://php.net/manual/en/function.sort.php for information on sorting arrays.
You should also start using PDO or mysqli as the mysql functions have been officially deprecated.
I also strongly advise you to not put multiple tags in one database field.

Retrieve and display comments/queries from database

I'm developing in php/sql a web application where users will be able to post items that they'd like to sell ( kinda like ebay ). I want non-members to be able to comment on the items or ask queries about items.
My problem is I want to display each item as well as any comment/query made about that item, in a similar manner as the way Facebook wall works.
I want to "append comments"(if any) to each item. The comments table is linked to the items table via column item_id. And the items table is linked to users table via column user_id. I have left joined users table with items table to display item details, i tried to left join comments table as well so that there are 3 joined tables.
That fails because no comments are displayed and only one item is displayed, despite there being multiple entries in each table. Here is the code i,m using.
$database->query
('
SELECT sale.*, query.*, users.id AS userid, users.username as user
FROM sale
LEFT JOIN users ON sale.user_id = users.id
LEFT JOIN query on sale.id = query.item_id
where category = "$category" ORDER BY sale.id DESC
');
$show = " "; //variable to hold items and comments
if ($database->count() == 0) {
// Show this message if there are no items
$show .= "<li class='noitems'>There are currently no items to display.</li>" ;
} else {
$show .= "<li>";
while ( $items = $database->statement->fetch(PDO::FETCH_ASSOC) )
{
$show .= "
//show item details in html
";
while( $query = $database->statement->fetch(PDO::FETCH_ASSOC) )
{
$show .= "
//show queries below item details
";
}
$show .= "</li>" ;
}
Welcome to Stackoverflow!
I recommend you taking a look at pdo. If you are already using mysql_ functions, then I recommend you switch. More on that can be found here.
Now that your pointed to the direction of to what functions to use when connecting/running queries, you now should create your tables. I use phpmyadmin for managing my database, I find it very good, but it's up to you what you use. Once you've decided on the service you use to manage your database, you should then learn how to use it by doing some google searches.
Now you need to set up your table and structure it correctly. If you say you're having items, then you should make a table called items. Next create the columns to the properties of the items. Also I recommend reading about Database Normalization, which is a key aspect of setting up your SQL tables Etc.
Once you have everything set up, you've connected to your database successfully Etc. You now need to set up the "Dynamic Page". What I mean by this is, there's only one page, say called 'dynamic', then a variable is passed to the url. These are called GET HTTP requests. Here's an example of what one would look like: http://example.com/item?id=345.
If you've noticed, you'll see the ? then the id variable defined to 345. You can GRAB this variable from the url by accessing the built in PHP array called $_GET[]. You can then type in your variable name you want to fetch into the []'s. Here's an example.
<?php
$data = $_GET['varname']; // get varname from the url
if(isnumeric($data)){ // is it totally made out of numbers?
$query = "SELECT fieldname FROM table WHERE id=:paramname";
$statement = $pdo->prepare($query); // prepare's the query
$statement->execute(array(
'paramname'=>$data // binds the parameter 'paramname' to the $data variable.
));
$result = $statement->fetch(PDO::FETCH_ASSOC); // grabs the result of the query
$result = $result['fieldname'];
echo 'varname was found in the database with the id equal to:'.$data.', and the result being: '.$result;
}
?>
So now you can see how you can grab the variable from the url and dynamically change the content with-in the page from that!
Hope this helped :)

PHP Select List To Drive Table Display

I'm having a tough time figuring out how to have a select list drive what is returned in a table. Scenario, there are a list of projects, pending what project your user has access to a subset of items are returned.
Here is some code:
query:
$q = "SELECT DISTINCT projectid, projectname FROM projects where active=1";
select list construction:
//variable for projects list select list name
$dropdown = "Projects Lists \n <select name=\"ProjectsLists\">";
//loop results
while ($row = mysql_fetch_assoc($result)){
$dropdown .= "\r\n<option value='{$row['projectid']}'>{$row['projectname']}</option>";
}//end while
$dropdown .= "\r\n</select>";
echo $dropdown;
Then what i'd like to do is display items returned from a query that needs to be run when the select list is select:
$s_query = "SELECT contentname, contentlocation FROM projectscontent WHERE projectname=<select list value>";
I'm having trouble figuring out if i can capture the selected value. If so, how? I thought i could maybe do $_GET['selectlistname']; but i don't think that is right.
you have to use jquery event .change() this will help you for what you want.
For example:
Add an id in you select options
like $dropdown = "Projects Lists \n <select id=\"mylist\" name=\"ProjectsLists\">";
now with jquery use something like this:
$('#mylist').change(
//provide you selected value
var proName = $(this).val();
//call ajax
$.ajax({
url: 'queryPage.php',
data: 'proName=' + proName,
success: function(data){
$('#result').html(data);
}
});
);
queryPage.php:
//$_REQUEST['proName'] provide you select product name
$productname = mysql_real_escape_string( $_REQUEST['proName'] );
// Now start your query
$s_query = "SELECT contentname, contentlocation FROM projectscontent
WHERE projectname='$productname' ";
now start to run the query and echo the result here on the same page, this will return the data to the page from where you call queryPage.php.
I personally use jQuery DataTables for this type of functionality. I generate a dropdown or group of dropdowns, then on click of a button I update my DataTable element. There are several tutorials on how to do this on the website.
I'm a little concerned, though, that your tables are a bit wonky. This should be very straightforward, and might require more tables than you're telling us about. I'd personally link my two tables on projectid if I was using the structure you're showing above. Then, I'd add an additional table (via inner join on userid) that links users.userid, permissions, and projectid. This would be queried into the second query in your example above to handle permissions.
When I'm generating my dropdown, I'm keeping that simple too. Each <option> would have a value = projectid and the display value would be the project name. On change of the select element listing the projects, I'd run a query (ajax preferrably) to get myself all the project details joined with permissions with where clauses to limit my results to the user, based on permissions. No need to do exotic "merged" values, etc.

Categories