I am trying to get rows out of 2 tables. The first query works. But the second doesn't. This is my code:
echo '<table width="100%">';
echo '<tr><td>Product</td><td>Quantity</td><td>Price</td><td>Remove</td></tr>';
foreach ($_SESSION['cart'] as $key => $cartproduct) {
list($productid, $productquantity) = split("\|", $cartproduct, 2);
global $db;
$result = $db->prepare('SELECT name FROM products WHERE ID= :ID LIMIT 1; SELECT price FROM prices WHERE productid = :ID AND quantity = :quantity LIMIT 1');
$result->bindParam(':ID', $productid);
$result->bindParam(':quantity', $productquantity);
$result->execute();
$row = $result->fetch();
if($result->RowCount() == 1){
echo '<tr><td>' . $row['name'] . '</td><td>' . $productquantity . '</td><td>' . $row['price'] . '</td><td>Remove</td></tr>'; //LINE15
}else{
unset($_SESSION['cart'][$key]);
}
}
echo '</table>';
The row name is from the products table and the name price is from the prices table. This is the error I get:
Notice: Undefined index: price in /var/www/html/design2/pages/cart.php on line 15
I am sure the query is working. Can anyone tell my what i am doing wrong?
You are receiving index not defined because of the way your query is structured. You have:
SELECT name FROM products WHERE ID= :ID LIMIT 1; SELECT price FROM prices WHERE productid = :ID AND quantity = :quantity LIMIT 1
This is structured to return 2 result sets. You grab the first result set here:
$row = $result->fetch();
But then you try to access $row['price'] which doesn't exist in that result set. That result set is only the result from the first SELECT. You can see this if you just var_dump($row) and see what your result set looks like.
It looks like you can combine your query so that you get one result set:
SELECT p.name, pp.price FROM products p
INNER JOIN prices pp ON p.ID = pp.productid
WHERE p.ID= :ID AND pp.quantity = :quantity
LIMIT 1;
If you can't combine the queries into one, then you should iterate over your result sets and access the relevant $row index. That would look something like:
while($row = $result->fetch()) {
if(isset($row['name'])) {
//do something
} else if(isset($row['price'])) {
//do something else
}
}
Some things to consider:
You may need a LEFT JOIN instead of an INNER JOIN. This depends on
whether or not products always have a corresponding record in the
prices table.
I'm not sure what you're trying to achieve with
LIMIT 1. You may need to consider and ORDER BY -- unless it really
doesn't matter which record you return in your result.
You should consider testing your variables $productid and $productquantity to verify they have your intended values after splitting $cartproduct. What if one is empty / blank ?
You should test your result before trying to access the result array at a specific index.
For example:
if(isset($row['name']) && isset($row['price'])) {
//echo your results
} else {
//return an error
}
Related
I have the following Mysql query:
$sql = "select r.brand AS brand, r.name AS name, r.cost AS cost, e.price AS price, d.shipping as shipping
FROM tab.rawproduct r
INNER JOIN price e ON r.housecode=e.housecode
INNER JOIN product d ON e.productid=d.productid
WHERE r.housecode='$housecode'";
The houscode is assigned to a variable which is then passed to the sql statement:
<label>Housecode:</label><input class="boxes" type="text" name="housecode" value="<?php echo $housecode; ?>"><br />
$housecode = $_POST['housecode'];
Housecode is submitted through a form with action set to $_SERVER[PHP_SELF]
I am trying to iterate over the results with PHP with the following:
$result = $con->query($sql);
if ($result->num_rows >0) {
while($row = mysqli_fetch_array($result)) {
$brand = $row['brand'];
$housecode = $row['housecode'];
$name = $row['name'];
$cost = $row['cost'];
$salesprice = $row['price'];
$shipraw = $row['shipping'];
}
} else {
echo "0 Results";
}
$con->close();
Nothing is getting returned when a user submits a housecode and the "0 Results" is echoed.
I have looked into this problem and read Lucas Knuth's post:
If two or more columns of the result have the same field names, the
last column will take precedence. To access the other column(s) of the
same name, you must use the numeric index of the column or make an
alias for the column. For aliased columns, you cannot access the
contents with the original column name. So, you can either use an AS
in your SQL-query to set other names for the doubled rows or use the
numbered indexes to access them.
So I have used the AS keyword in the above query but I still don't get any results. I have also tried changing to mysqli_fetch_row($result) and tried to assign the $row[0], 1 ... etc instead. Again no luck.
When I run Apache error_log I get the following:
Trying to get property of non-object on line 34. On line 34 and 35 I have:
if ($result->num_rows >0) {
while($row = mysqli_fetch_array($result)) {
Any help would be much appreciated.
Cheers
I have figured out the answer for myself.
The problem was that I was selecting just one database, ie tab.rawproduct BUT tables price e and procduct d are from a totally different database.
So the sql query should have been this:
$sql = "SELECT r.brand, r.name, r.cost, e.price, d.shipping FROM
tab.rawproduct r
INNER JOIN t1.price e on r.housecode=e.housecode
INNER JOIN t1.product d on e.productid=d.productid
WHERE r.housecode = '$housecode' ";
If found the error by checking the mysqli->errno:
if(!$result = $mysqli->query($sql)) {
echo "Error: Our query failed to execute and here is why: \n";
echo "Query: " . $sql . "\n";
echo "Errno: " . $mysqli->errno . "\n";
echo "Error: " . $mysqli->error . "\n";
exit;
}
Hopefully this may help someone else facing the same problem.
Thanks for all your comments and help.
I reproduced your example and I found a bug in your select query: you're missing the r.housecode.
$sql = "select r.brand AS brand, r.name AS name, r.cost AS cost, e.price AS price, d.shipping as shipping, r.housecode AS housecode
FROM tab.rawproduct r
INNER JOIN price e ON r.housecode=e.housecode
INNER JOIN product d ON e.productid=d.productid
WHERE r.housecode='$housecode'";
Check if the cross references match in your tables, because in my examples the rows are correctly returned
table price:
housecode productid price
HT0008 4 3400
HT0008 5 5400
table product:
shipping productid
64 4
78 5
table rawproduct:
brand name cost housecode
Cani bellaaa 63824 HT0008
From mysqli request I receive a result that contains a table with 5 columns and a number of rows. I would like to perform a calculation with my data that I just received and add the result of my calc in a NEW COLUMN in my array.
So in different words, I would like to add one column to the array and fill this column with results for each row.
My code so far looks as follows and of course only prints the array that I receive from my SQL query:
<?php
error_reporting(0);
require 'init1.php';
if($result = $db->query("Select * from (select * from(SELECT * FROM `scores`
ORDER BY `battle_id` ASC,user_id asc,score desc) as t1 GROUP BY
t1.battle_id, t1.user_id) as t2 order by `battle_id` ASC,score desc")){
if($count = $result->num_rows){
echo '<p>' , $count, '<p>';
while ($row = $result->fetch_object()){
echo $row->battle_id, ' ' , $row->user_id, ' ' , $row->score, '<br>';
}
//instead of just printing the existing array, I would like to perform a
//calculation and add a result in a new column at the end of every single
//row
}
}
If you use an Array you can simply 'define' a new item in your array to store the calculation result.
while ($row = $result->fetch_row()) {
// Calculation and other stuff here
$row['calc_result'] = $calculation_result;
}
Then in order to access it outside the while scope, you would need to store each row in another array, for example:
$stored_data = array();
while ($row = $result->fetch_row()) {
// Calculation and other stuff here
$row['calc_result'] = $calculation_result;
array_push( $stored_data, $row );
}
I want to output like this from the database:
Store name 1
--------------------
Product 1
Product 2
Store name 2
---------------------
Product 3
Product 4
and the query i use right now looks like this:
$query_stores = DB::query("SELECT * FROM `stores` LIMIT 16");
foreach($query_stores as $row){
echo $row['name'] . '<br>';
$query_products = DB::query("SELECT `id`, `name` FROM `products` WHERE `vendor` = %i ORDER BY RAND() LIMIT 10" , $row['id']);
foreach($query_products as $row2){
echo $row2['name'] . '<br>';
}
}
The code works (sort of) but i can't filter the stores that don't have any items in the products table.
Example output:
Store name 1
Store name 2
--------------------
Product 1
Product 2
Store name 3
Store name 4
---------------------
Product 3
Product 4
Store name 5
Is there a better way to run the code? Can the two queries be combined?
How to exclude the stores from output that don't have any items in the products table?
You're better off using a single query with a join statement and build an array of data to parse and display:
$sql = "SELECT s.id as store_id, s.name as store_name, p.id as product_id, p.name as product_name
FROM stores s
LEFT JOIN products p ON (s.id = p.vendor)
WHERE p.id IS NOT NULL
ORDER BY s.name ASC, p.name ASC
LIMIT 16";
$data = DB::query($sql);
After the query is run, $data will only contain stores that have products. The LEFT JOIN will make sure stores are the base information and if they have no products the product columns will be NULL. The WHERE clause makes sure that you filter out any stores with no products.
Setting up a structured array will make it easier to loop through your data.
$stores = []; // or if PHP version < 5.4 array();
foreach($data as $row) {
if (!array_key_exists($row['store_id'], $stores)) {
$stores[$row['store_id']] = [
'store_name' => $row['store_name'],
'products' => [],
];
}
$stores[$row['store_id']]['products'][$row['product_id']] = $row['product_name'];
}
And for outputting:
foreach ($stores as $store_id => $store) {
echo $store['name'] .'<br/>';
foreach ($store['products'] as $product_id => $product_name) {
echo $product_name .'<br/>';
}
}
Try something like this to reorder your queries so you can check if store is empty and then print if is not and if is empty then dont print it.
$query_stores = DB::query("SELECT * FROM `stores` LIMIT 16");
foreach($query_stores as $row){
// put $query_products in front of echoing and check if store is empty
$query_products = DB::query("SELECT `id`, `name` FROM `products` WHERE `vendor` = %i ORDER BY RAND() LIMIT 10" , $row['id']);
// Here you check if result is empty
if(mysql_num_rows($query_products) > 0){
echo $row['name'] . '<br>';
foreach($query_products as $row2){
echo $row2['name'] . '<br>';
}
}
}
You could use mysql_num_rows(); function and check if number of result is < 0
I have a search results page which displays items from a MySQL database (table1). The code I am using to the display the results is:
if (!empty($data)) {
foreach ($data as $item) {
echo '<div class="item">';
if (strlen($item['item_desc']) > 10) {
if (strlen($item['item_link']) > 10) {
echo '<a href="/item.php?id='.$item['item_id'].'">';
} else {
echo 'No Results Found';
}
}
}
}
The images for each search result are stored in a separate table (table2). I am trying to use the code below to count the number of images in table2 for each result and display the number against each result on the search results page, but it returns a 0 value?
$result=mysql_query("SELECT count(*) as total from table2 where id = '" .$item['item_id']. "'");
$query=mysql_fetch_assoc($result);
echo $query['total'];
I am missing some data about your database structure but I can imagine you store your image id as an integer and you are requesting the count with the id being a string.
So, if I'm true this may help. Remove the quotes around the php variable with the item_id
"SELECT count(*) as total from table2 where id = " .$item['item_id'];
you can try this..
$str=$item['item_id'];
mysql_query("SELECT count(*) as total from table2 where id = '$str'");
There is a mysql function to count rows outputted from your mysql query, it is mysql_num_rows(). From what I can understand about your database your code could be this:
$item_id = $item['item_id'];
$result = mysql_query("SELECT * FROM table2 where id = '$item_id'");
$count = mysql_num_rows($result);
echo $count;
This will output how many records match your query.
I am running a sql query, that pulls the id, catid, name, subof from two tables using inner join.
select shop.id, shop.catid, shop.name, shop_cat.catname, shop_cat.subof from shop inner join shop_cat on shop.catid = shop_cat.id where shop.active='1' order by shop_cat.catname, shop.name
Now this results everything i need but I need to loop through the result and do another sql query for the subof value (which is a value, the value being a ID number of the shop_cat). I need to pull the catname of the subof value #, then update the result/array field subof to the name of the cat.
So if the original query gave me a value of 15 for subof, it would do a select catname from shop.cat where id='15' i would take the catname from that query and then update subof = catname for every value in the original result that has a subof value.
EDIT 3/23/13 12:30pm MST: Using more of the code that Opeyemi wrote, to explain more of what I need. I am not sure how else to explain it...
$q = "select shop.id, shop.catid, shop.name, shop_cat.catname, shop_cat.subof from shop inner join shop_cat on shop.catid = shop_cat.id where shop.active='1' order by shop_cat.catname, shop.name";
$r = mysql_query();
while(list($shopid, $catid, $name, $catname, $subof) = mysql_fetch_array($r)) {
$getname = mysql_query("select catname from shop_cat where id='$subof'");
$rowname = mysql_fetch_assoc($getname);
//code to update array to change value of $subof to new $rowname['catname']
}
The DB query runs, gets me my values.
I then need to run a loop of some kind, which will loop through every result PHP aquired from the query. This loop will take the subof value (which is a integer ID number) then run a query to get the value catname of that integer value. Then the loop will update the current result and change the subof value from the integer to the catname pulled from the DB in the loop.
I do not need to update the database at anytime, I need to update the result/array from the first query.
What you need to do is to store the resultset in an array and replace within the array.
$q = "select shop.id, shop.catid, shop.name, shop_cat.catname, shop_cat.subof from shop inner join shop_cat on shop.catid = shop_cat.id where shop.active='1' order by shop_cat.catname, shop.name";
$r = mysql_query();
$dataset = array();
// Store result in an array
while($assoc = mysql_fetch_assoc($r)) {
$dataset[] = $assoc;
}
// Update array
foreach($dataset as $data) {
$getname = mysql_query("select catname from shop_cat where id='{$data['subof']}'");
$rowname = mysql_fetch_assoc($getname);
// replace data
replace_dataset($data['subof'], $rowname);
}
function replace_dataset($key, $newname) {
global $dataset;
foreach($dataset as $k => $data) {
if ($data['id'] == $key)
$dataset[$k]['subof'] = $newname;
}
}
Are you asking how to do this in PHP or what? If you are looking for how to loop results in PHP it is as simple as this
$q = "select shop.id, shop.catid, shop.name, shop_cat.catname, shop_cat.subof from shop inner join shop_cat on shop.catid = shop_cat.id where shop.active='1' order by shop_cat.catname, shop.name";
$r = mysql_query();
while(list($shopid, $catid, $name, $catname, $subof) = mysql_fetch_array($r)) {
// the values from the query are assigned to the variables
// $shopid, $catid, $name, $catname, $subof in that order already
mysql_query("update shop_cat set subof=catname where id='$subof'");
// My interpretation of your query can be wrong though
// But you should get the idea
}
You can use mysql_fetch_assoc() or mysql_fetch_array() or mysql_fetch_row() functions to fetch the row and can put your looping concept on it.
After that you can use mysql_fetch_field() to fetch field subof and id from it.
and update the database after that
You can check the following links
http://www.php.net/manual/en/function.mysql-fetch-array.php
http://www.php.net/manual/en/function.mysql-fetch-assoc.php
http://www.php.net/manual/en/function.mysql-fetch-field.php
I hope you get some idea.