Increase a number based on another number - php

I'm trying to find a way to increase a number in my database which I enter manually based on another number that is updated automatically from a device.
In my database I have a few columns, but the one that matters are
cancelled_meter mec_in demult.
``cancelled_meter`` is the column that is updated automatically
``mec_in`` is the column that is input manually
``demult`` is the column that is also updated automatically
These columns are all numbers (eg. cancelled_meter = 428080.00, mec_in = 2174827.00 and demult is usually 1, 100 or 1000.
Here's something I was trying to do in PHP:
<?php
$sql = "SELECT id, cancelled_meter, total_drop, mec_in, mec_out, demult, val_pct
FROM machtest ORDER BY id DESC LIMIT 1";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>ID</th>
<th>Coin IN Meter</th>
<th>Coin OUT Meter</th>
<th>Demultiplication</th>
<th>Pt Value</th>
<th>Total IN</th>
<th>Total OUT</th>
</tr>";
while($row = $result->fetch_assoc()) {
$offset_in = $row["cancelled_meter"] - $row["mec_in"] * -1;
$abbs_in = abs($offset_in);
$round_in = abs($row["cancelled_meter"] / $row["demult"] + $abbs_in);
$offset_out = $row["total_drop"] - $row["mec_out"] * -1;
$abbs_out = abs($offset_out);
$round_out = abs($row["total_drop"] / $row["demult"] + $abbs_out);
echo "<tr>
<td>"
.$row["id"]."</td>".
"<td>"
.$row["cancelled_meter"]."</td>".
"<td>"
.$row["total_drop"]."</td>".
"<td>"
.$row["demult"]."</td>".
"<td>"
.$row["val_pct"]."</td>".
"<td>"
.$round_in."</td>".
"<td>"
.round($row["total_drop"] / $row["demult"] + $abbs_out)."</td>
<tr>";
}
echo "</table>";
} else {
echo "0 results";
}
$conn->close();
?>
This kind of works but I want to display mec_in which updates automatically when cancelled_meter changes and that only displays something else.
One more thing is that mec_in can be greater or lesser then cancelled_meter that's why I need a positive result.
I was trying something like mec_in = cancelled_meter / demult + some offset that's between cancelled_meter and mec_in.
I'm trying to figure this out, but I'm a beginner, so if anyone has some suggestions I would very much appreciate it.
PS. I was trying to calculate this on the php file but in the MySQL is good too if anyone knows how.

I don't know what wase in my head, but after adding this $total = abs($round_in - $row["offset_in"]); worked just fine. I got offset_in column by doing $round_in -
mec_in and then $round_in - $row["offset_in"]); wich gives the desired result. Thank you for your input.

Related

PHP If the number of an element was more than an amount, separate elements into two or more pages [duplicate]

I have some code that LIMITs data to display only 4 items per page. The column I'm using has about 20-30 items, so I need to make those spread out across the pages.
On the first page, I have:
$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4");
{
echo "<tr>";
echo "<td align='center'><img src=\"" . $row['picturepath'] . "\" /></td>";
echo "<td align='center'>" . $row['name'] . "</td> <td align='center'> <input type='button' value='More Info'; onclick=\"window.location='more_info.php?';\"> </td>";
echo "<td align='center'>" . $row['price'] . "</td> <td align='center'> <input type='button' value='Add to Order' onclick=''> </td>";
echo "</tr>";
}
echo "</table>";
mysqli_close($con);
?>
<table width="1024" align="center" >
<tr height="50"></tr>
<tr>
<td width="80%" align="right">
NEXT
</td>
<td width="20%" align="right">
MAIN MENU
</td>
</tr>
</table>
You'll notice towards the bottom of the page my anchor tag within lists the second page, "itempage2.php". In item page 2, I have the same code, except my select statement lists the offset of 4.
$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4 offset 4");
This works, this way when there is a pre-determined number of items within my database. But it's not that good. I need to create a new page only if there are more items, not hard-coded into it like it is now.
How can I create multiple pages without having to hard-code each new page, and offset?
First off, don't have a separate server script for each page, that is just madness. Most applications implement pagination via use of a pagination parameter in the URL. Something like:
http://yoursite.com/itempage.php?page=2
You can access the requested page number via $_GET['page'].
This makes your SQL formulation really easy:
// determine page number from $_GET
$page = 1;
if(!empty($_GET['page'])) {
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
if(false === $page) {
$page = 1;
}
}
// set the number of items to display per page
$items_per_page = 4;
// build query
$offset = ($page - 1) * $items_per_page;
$sql = "SELECT * FROM menuitem LIMIT " . $offset . "," . $items_per_page;
So for example if input here was page=2, with 4 rows per page, your query would be:
SELECT * FROM menuitem LIMIT 4,4
So that is the basic problem of pagination. Now, you have the added requirement that you want to understand the total number of pages (so that you can determine if "NEXT PAGE" should be shown or if you wanted to allow direct access to page X via a link).
In order to do this, you must understand the number of rows in the table.
You can simply do this with a DB call before trying to return your actual limited record set (I say BEFORE since you obviously want to validate that the requested page exists).
This is actually quite simple:
$sql = "SELECT your_primary_key_field FROM menuitem";
$result = mysqli_query($con, $sql);
$row_count = mysqli_num_rows($result);
// free the result set as you don't need it anymore
mysqli_free_result($result);
$page_count = 0;
if (0 === $row_count) {
// maybe show some error since there is nothing in your table
} else {
// determine page_count
$page_count = (int)ceil($row_count / $items_per_page);
// double check that request page is in range
if($page > $page_count) {
// error to user, maybe set page to 1
$page = 1;
}
}
// make your LIMIT query here as shown above
// later when outputting page, you can simply work with $page and $page_count to output links
// for example
for ($i = 1; $i <= $page_count; $i++) {
if ($i === $page) { // this is current page
echo 'Page ' . $i . '<br>';
} else { // show link to other page
echo 'Page ' . $i . '<br>';
}
}
A dozen pages is not a big deal when using OFFSET. But when you have hundreds of pages, you will find that OFFSET is bad for performance. This is because all the skipped rows need to be read each time.
It is better to remember where you left off.
If you want to keep it simple go ahead and try this out.
$page_number = mysqli_escape_string($con, $_GET['page']);
$count_per_page = 20;
$next_offset = $page_number * $count_per_page;
$cat =mysqli_query($con, "SELECT * FROM categories LIMIT $count_per_page OFFSET $next_offset");
while ($row = mysqli_fetch_array($cat))
$count = $row[0];
The rest is up to you.
If you have result comming from two tables i suggest you try a different approach.
Use .. LIMIT :pageSize OFFSET :pageStart
Where :pageStart is bound to the_page_index (i.e. 0 for the first page) * number_of_items_per_pages (e.g. 4) and :pageSize is bound to number_of_items_per_pages.
To detect for "has more pages", either use SQL_CALC_FOUND_ROWS or use .. LIMIT :pageSize OFFSET :pageStart + 1 and detect a missing last (pageSize+1) record. Needless to say, for pages with an index > 0, there exists a previous page.
If the page index value is embedded in the URL (e.g. in "prev page" and "next page" links) then it can be obtained via the appropriate $_GET item.

How do i get specific records with sql? [duplicate]

I have some code that LIMITs data to display only 4 items per page. The column I'm using has about 20-30 items, so I need to make those spread out across the pages.
On the first page, I have:
$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4");
{
echo "<tr>";
echo "<td align='center'><img src=\"" . $row['picturepath'] . "\" /></td>";
echo "<td align='center'>" . $row['name'] . "</td> <td align='center'> <input type='button' value='More Info'; onclick=\"window.location='more_info.php?';\"> </td>";
echo "<td align='center'>" . $row['price'] . "</td> <td align='center'> <input type='button' value='Add to Order' onclick=''> </td>";
echo "</tr>";
}
echo "</table>";
mysqli_close($con);
?>
<table width="1024" align="center" >
<tr height="50"></tr>
<tr>
<td width="80%" align="right">
NEXT
</td>
<td width="20%" align="right">
MAIN MENU
</td>
</tr>
</table>
You'll notice towards the bottom of the page my anchor tag within lists the second page, "itempage2.php". In item page 2, I have the same code, except my select statement lists the offset of 4.
$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4 offset 4");
This works, this way when there is a pre-determined number of items within my database. But it's not that good. I need to create a new page only if there are more items, not hard-coded into it like it is now.
How can I create multiple pages without having to hard-code each new page, and offset?
First off, don't have a separate server script for each page, that is just madness. Most applications implement pagination via use of a pagination parameter in the URL. Something like:
http://yoursite.com/itempage.php?page=2
You can access the requested page number via $_GET['page'].
This makes your SQL formulation really easy:
// determine page number from $_GET
$page = 1;
if(!empty($_GET['page'])) {
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
if(false === $page) {
$page = 1;
}
}
// set the number of items to display per page
$items_per_page = 4;
// build query
$offset = ($page - 1) * $items_per_page;
$sql = "SELECT * FROM menuitem LIMIT " . $offset . "," . $items_per_page;
So for example if input here was page=2, with 4 rows per page, your query would be:
SELECT * FROM menuitem LIMIT 4,4
So that is the basic problem of pagination. Now, you have the added requirement that you want to understand the total number of pages (so that you can determine if "NEXT PAGE" should be shown or if you wanted to allow direct access to page X via a link).
In order to do this, you must understand the number of rows in the table.
You can simply do this with a DB call before trying to return your actual limited record set (I say BEFORE since you obviously want to validate that the requested page exists).
This is actually quite simple:
$sql = "SELECT your_primary_key_field FROM menuitem";
$result = mysqli_query($con, $sql);
$row_count = mysqli_num_rows($result);
// free the result set as you don't need it anymore
mysqli_free_result($result);
$page_count = 0;
if (0 === $row_count) {
// maybe show some error since there is nothing in your table
} else {
// determine page_count
$page_count = (int)ceil($row_count / $items_per_page);
// double check that request page is in range
if($page > $page_count) {
// error to user, maybe set page to 1
$page = 1;
}
}
// make your LIMIT query here as shown above
// later when outputting page, you can simply work with $page and $page_count to output links
// for example
for ($i = 1; $i <= $page_count; $i++) {
if ($i === $page) { // this is current page
echo 'Page ' . $i . '<br>';
} else { // show link to other page
echo 'Page ' . $i . '<br>';
}
}
A dozen pages is not a big deal when using OFFSET. But when you have hundreds of pages, you will find that OFFSET is bad for performance. This is because all the skipped rows need to be read each time.
It is better to remember where you left off.
If you want to keep it simple go ahead and try this out.
$page_number = mysqli_escape_string($con, $_GET['page']);
$count_per_page = 20;
$next_offset = $page_number * $count_per_page;
$cat =mysqli_query($con, "SELECT * FROM categories LIMIT $count_per_page OFFSET $next_offset");
while ($row = mysqli_fetch_array($cat))
$count = $row[0];
The rest is up to you.
If you have result comming from two tables i suggest you try a different approach.
Use .. LIMIT :pageSize OFFSET :pageStart
Where :pageStart is bound to the_page_index (i.e. 0 for the first page) * number_of_items_per_pages (e.g. 4) and :pageSize is bound to number_of_items_per_pages.
To detect for "has more pages", either use SQL_CALC_FOUND_ROWS or use .. LIMIT :pageSize OFFSET :pageStart + 1 and detect a missing last (pageSize+1) record. Needless to say, for pages with an index > 0, there exists a previous page.
If the page index value is embedded in the URL (e.g. in "prev page" and "next page" links) then it can be obtained via the appropriate $_GET item.

PHP beginner with MySQL trouble

I am creating a website in which users can log on and review Tablet PC's
On tablet page visitors to the site can see the reviews left by other users. Despite users being able to review 5 tablets, the 'ipad' page for example will only show 'ipad' review. The code can be seen below:
<?php
include('connection.php');
$result = mysql_query("SELECT * FROM tt_review WHERE product = 'Apple iPad'");
echo "<table border='1'>
<tr>
</tr>";
while($row = mysql_fetch_array($result)) //This function is calling the results variable and displaying them within the rows below
{
echo "<tr>"; //this code tells the page to output the table rows that are defined above
echo "<td>" . $row['name'] . "</td>";
echo "<td>" . $row['date'] . "</td>"; //each row is then executed using the table data function
echo "<td>" . $row['product'] . "</td>";
echo "<td>" . $row['star'] . "</td>";
echo "<td>" . $row['comment'] . "</td>";
echo "</tr>";
}
echo "</table>";
?>
I have a field in my database called 'star' which is the rating the users have gave the tablet. 1, 2, 3, 4 or 5 are the options. I need code that works out the average of the 'star' rating from the 'ipad' page and to display an image based on whatever number it is.
All help is greatly appreciated as I am a newcomer and cant seem to find the answer online.
Thanks
Jonathan
Use mysqli to connect to the database. Then you can use the AVG function to calculate average of the column star. Execute the query and fetch the array and then print the average. Then you can use simple switch case or if else to display the image according to the average obtained.
<?php
$db = mysqli_connect("host","user","pass","database");
$query = "SELECT AVG(column_name) FROM table_name";
$result = mysqli_query($db, $query);
$array = mysqli_fetch_row($result);
$average = $array[0];
echo $average;
?>
From what I understand you want to calculate the average rating for each tablet. If yes, you can just fetch the star column for the particular tablet from the database and extract it as an array and run a simple for-each loop to calculate the sum and average of the rating for that tablet and based on the average it calculated, an indication can be placed on the screen in the form of images or something else.
I'm with the others regarding using 'mysql_*' functions, but I won't go into that here as that is not relevant to your question.
To find the average you add all of the total stars together and divide by the quantity. My suggestion is to first find out how many rows are returned.
$totalStars = count($result);
You also need to know what the sum is of the column. This is done using SUM(column). Like so:
$result = mysql_query("SELECT SUM(star) as TotalStars, name, date, product, star, comment FROM tt_review WHERE product = 'Apple iPad'");
However, you can also add a counter to your code, like so:
$x = 0;
while($row = mysql_fetch_array($result)) {
$x += $row['star'];
// your other code
$x++;
}
Finally, at the end, you can display the average by doing something like:
if ($totalStars != 0 ) {
$average = $x / $totalStars;
echo "This product's average stars is " . $average . PHP_EOL;
} else {
// handle the divide by zero issue
}
When it comes to displaying a particular image, well, you can use a conditional statement or something like:
if ($average > 0 && $average <= 1) {
echo "<img src='images/star1.jpg' alt='star1' />";
} else if ($average > 1 && $average <= 1.5) {
// etc etc etc
}
Hope that helped some.
As mentioned, use PDO to connect to the database. Here's how you get the average stars:
$i = 0;
$totalStars = 0;
while($row = mysql_fetch_array($result))
{
$totalStars += $row['star'];
// rest of your code
$i++;
}
echo 'Average stars = '.($totalStars/$i);
As pointed out by others, Mysql has an AVG() function you can use for this exact purpose.
SELECT AVG(star) AS rating FROM tt_review WHERE product = 'Apple iPad' GROUP BY product;
or, to get the star rating for all products you leave off the WHERE
SELECT AVG(star) AS rating FROM tt_review GROUP BY product;
If you just want your rating to be 1,2,3,4, or 5
SELECT ROUND(AVG(star), 0) AS rating FROM tt_review WHERE product = 'Apple iPad' GROUP BY product;
And if you want the rounded number to skew up (a common desire)
SELECT CEILING(AVG(star)) AS rating FROM tt_review WHERE product = 'Apple iPad' GROUP BY product;

Bundling information by date

I have a pretty good idea of how to do this, but I'm not exactly sure... how to do it , if that makes sense. This is still my first day (going on second without sleep) of learning PHP and I'm trying to complete this project before I call it quits. This is actually all that's left before I can call it quits and be happy with myself. So here's the thing.
I know I've asked quite a few questions today, hopefully this is the last one..
Currently my code pulls information from my database and displays it into a table, like so:
Now, this is great for the feature where I want to list the last 15 transactions, which is what my following code does, please excuse anything that's not done efficiently as it's my first day.
<html>
<table border="1">
<tr>
<th>Transaction Date</th>
<th>Transaction Amount</th>
<th>Item Name</th>
<th>Quantity</th>
</tr>
<?php
require_once 'Config.php';
require_once 'Connection.php';
$totalTransactions = 0;
$totalProfit = 0;
$testquery = "SELECT * FROM $tbl_name WHERE DATE($tbl_name.Date)
BETWEEN DATE_SUB(CURDATE(), INTERVAL 15 DAY) AND CURDATE()";
$results = mysql_query($testquery) or die (mysql_error());
while($row = mysql_fetch_array($results))
{
$totalTransactions += 1;
$totalProfit += $row[$ROW_AMOUNT];
echo "<tr>";
echo "<td align='center'>".$row[$ROW_DATE] . "</td>";
echo "<td align='center'>$". number_format($row[$ROW_AMOUNT], 2) . "</td>";
echo "<td align='center'>null</td>";
echo "<td align='center'>null</td>";
echo "<tr>";
}
echo "<tr>";
echo "<td align='center'><strong>SUM:</strong></td>";
echo "<td align='center'><strong>$".number_format($totalProfit, 2)."</strong></td>";
echo "<td align='center'><strong> </strong></td>";
echo "<td align='center'><strong> </strong></td>";
echo "<tr>";
?>
</table>
</html>
Now, I'm trying to figure out how I can group it like such in a table
[Day] - [Sum]
I understand how to get the sum for the data, obviously because that's what the script above does for the last 15 transactions, but how about grouping them together?
an example of the output I'm looking for is like this (This was done in pure HTML and is just an example of what I'm trying to achieve)
To re-word my question more efficiently, I'm trying to create another table that shows the sum for each date that there is "Transactions" for.
You have to group your columns using the GROUP BY clause and then aggregate the sum of Transaction Amount:
SELECT Date, SUM([Transaction Amount])
FROM $tbl_name
WHERE DATE($tbl_name.Date)
BETWEEN DATE_SUB(CURDATE(), INTERVAL 15 DAY) AND CURDATE()
GROUP BY Date
Please note that you may have to put quotes or something else around the column name Transaction Amount, this is TSQL syntax, I'm not sure how it's done in MySQL.

Pagination using MySQL LIMIT, OFFSET

I have some code that LIMITs data to display only 4 items per page. The column I'm using has about 20-30 items, so I need to make those spread out across the pages.
On the first page, I have:
$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4");
{
echo "<tr>";
echo "<td align='center'><img src=\"" . $row['picturepath'] . "\" /></td>";
echo "<td align='center'>" . $row['name'] . "</td> <td align='center'> <input type='button' value='More Info'; onclick=\"window.location='more_info.php?';\"> </td>";
echo "<td align='center'>" . $row['price'] . "</td> <td align='center'> <input type='button' value='Add to Order' onclick=''> </td>";
echo "</tr>";
}
echo "</table>";
mysqli_close($con);
?>
<table width="1024" align="center" >
<tr height="50"></tr>
<tr>
<td width="80%" align="right">
NEXT
</td>
<td width="20%" align="right">
MAIN MENU
</td>
</tr>
</table>
You'll notice towards the bottom of the page my anchor tag within lists the second page, "itempage2.php". In item page 2, I have the same code, except my select statement lists the offset of 4.
$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4 offset 4");
This works, this way when there is a pre-determined number of items within my database. But it's not that good. I need to create a new page only if there are more items, not hard-coded into it like it is now.
How can I create multiple pages without having to hard-code each new page, and offset?
First off, don't have a separate server script for each page, that is just madness. Most applications implement pagination via use of a pagination parameter in the URL. Something like:
http://yoursite.com/itempage.php?page=2
You can access the requested page number via $_GET['page'].
This makes your SQL formulation really easy:
// determine page number from $_GET
$page = 1;
if(!empty($_GET['page'])) {
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
if(false === $page) {
$page = 1;
}
}
// set the number of items to display per page
$items_per_page = 4;
// build query
$offset = ($page - 1) * $items_per_page;
$sql = "SELECT * FROM menuitem LIMIT " . $offset . "," . $items_per_page;
So for example if input here was page=2, with 4 rows per page, your query would be:
SELECT * FROM menuitem LIMIT 4,4
So that is the basic problem of pagination. Now, you have the added requirement that you want to understand the total number of pages (so that you can determine if "NEXT PAGE" should be shown or if you wanted to allow direct access to page X via a link).
In order to do this, you must understand the number of rows in the table.
You can simply do this with a DB call before trying to return your actual limited record set (I say BEFORE since you obviously want to validate that the requested page exists).
This is actually quite simple:
$sql = "SELECT your_primary_key_field FROM menuitem";
$result = mysqli_query($con, $sql);
$row_count = mysqli_num_rows($result);
// free the result set as you don't need it anymore
mysqli_free_result($result);
$page_count = 0;
if (0 === $row_count) {
// maybe show some error since there is nothing in your table
} else {
// determine page_count
$page_count = (int)ceil($row_count / $items_per_page);
// double check that request page is in range
if($page > $page_count) {
// error to user, maybe set page to 1
$page = 1;
}
}
// make your LIMIT query here as shown above
// later when outputting page, you can simply work with $page and $page_count to output links
// for example
for ($i = 1; $i <= $page_count; $i++) {
if ($i === $page) { // this is current page
echo 'Page ' . $i . '<br>';
} else { // show link to other page
echo 'Page ' . $i . '<br>';
}
}
A dozen pages is not a big deal when using OFFSET. But when you have hundreds of pages, you will find that OFFSET is bad for performance. This is because all the skipped rows need to be read each time.
It is better to remember where you left off.
If you want to keep it simple go ahead and try this out.
$page_number = mysqli_escape_string($con, $_GET['page']);
$count_per_page = 20;
$next_offset = $page_number * $count_per_page;
$cat =mysqli_query($con, "SELECT * FROM categories LIMIT $count_per_page OFFSET $next_offset");
while ($row = mysqli_fetch_array($cat))
$count = $row[0];
The rest is up to you.
If you have result comming from two tables i suggest you try a different approach.
Use .. LIMIT :pageSize OFFSET :pageStart
Where :pageStart is bound to the_page_index (i.e. 0 for the first page) * number_of_items_per_pages (e.g. 4) and :pageSize is bound to number_of_items_per_pages.
To detect for "has more pages", either use SQL_CALC_FOUND_ROWS or use .. LIMIT :pageSize OFFSET :pageStart + 1 and detect a missing last (pageSize+1) record. Needless to say, for pages with an index > 0, there exists a previous page.
If the page index value is embedded in the URL (e.g. in "prev page" and "next page" links) then it can be obtained via the appropriate $_GET item.

Categories