Calculating total of rows - php

I fetching and displaying records from database like this
SELECT purchorders.orderno,
suppliers.suppname,
purchorders.orddate,
purchorders.deliverydate,
purchorders.initiator,
purchorders.requisitionno,
purchorders.allowprint,
purchorders.status,
suppliers.currcode,
currencies.decimalplaces AS currdecimalplaces,
SUM(purchorderdetails.unitprice*purchorderdetails.quantityord) AS ordervalue
FROM purchorders
INNER JOIN purchorderdetails
ON purchorders.orderno = purchorderdetails.orderno
INNER JOIN suppliers
ON purchorders.supplierno = suppliers.supplierid
INNER JOIN currencies
ON suppliers.currcode=currencies.currabrev
WHERE purchorders.orderno=purchorderdetails.orderno
GROUP BY purchorders.orderno,
suppliers.suppname,
purchorders.orddate,
purchorders.initiator,
purchorders.requisitionno,
purchorders.allowprint,
purchorders.status,
suppliers.currcode,
currencies.decimalplaces LIMIT 5
I am getting the result properly. But i want to calculate and display the result of ordervalues which i have displayed (total of all 5 as i limit it to 5)
I tried doing like this
$SalesOrdersResult2 = DB_query($SQL,$db);
while ($row = DB_fetch_array($SalesOrdersResult2))
{
$FormatedOrderValue2 = locale_number_format($row['ordervalue'],$row['currdecimalplaces']);
$Total = $array_sum($row['ordervalue']);
$FormatedOrderDate1 = ConvertSQLDate($row['orddate']);
$FormatedDelDate1 = ConvertSQLDate($row['deliverydate']);
echo " <tr><td> " . $row['suppname'] . " </td>";
echo " <td>$FormatedOrderDate1</td><td>$FormatedDelDate1</td><td> " . $row['initiator'] . " </td><td>$FormatedOrderValue2</td><td> " . $row['status'] . " </td></tr> ";
}
echo "<tr><td colspan='3'>Total---</td><td colspan='2'>$Total</td></tr></tbody>";
But it says "Fatal error: Function name must be a string in ..."
Somebody please help me in doing this
Thanks

I suspect you're trying to do something like this?:
$SalesOrdersResult2 = DB_query($SQL, $db);
$Total = 0;
while ($row = DB_fetch_array($SalesOrdersResult2))
{
$FormatedOrderValue2 = locale_number_format($row['ordervalue'],$row['currdecimalplaces']);
$Total += $row['ordervalue'];
$FormatedOrderDate1 = ConvertSQLDate($row['orddate']);
$FormatedDelDate1 = ConvertSQLDate($row['deliverydate']);
echo " <tr><td> " . $row['suppname'] . " </td>";
echo " <td>$FormatedOrderDate1</td><td>$FormatedDelDate1</td><td> " . $row['initiator'] . " </td><td>$FormatedOrderValue2</td><td> " . $row['status'] . " </td></tr> ";
}
echo "<tr><td colspan='3'>Total---</td><td colspan='2'>$Total</td></tr></tbody>";

Remove the $ before array_sum.

Related

Check if two ranges intersect in a database with php

I have a database that has 2 columns Left_From and Left_To I need to basically check both columns with each row in the database to see if there is any overlapping ranges. So lets say there are 37 rows returned I need to check each row 37 times. I have tried array_intersect() with ranges and multiple loops. I have also tried BETWEEN in mysql but that does do what I need it to either. When I tried the between method I have two loops that I thought would take these two
$newstart[$crow] = $row['LEFT_FROM'];
$newend[$crow] = $row['LEFT_TO'];
and compare them to the new data that would be looped through 37 times because of $row2.
//attempt at BETWEEN
$newstart = array();
$newend = array();
$crow = 0;
while ($row = mysqli_fetch_array($get)) {
$newstart[$crow] = $row['LEFT_FROM'];
$newend[$crow] = $row['LEFT_TO'];
while ($row2 = mysqli_fetch_array($get)) {
$newsql = "SELECT * FROM database+table WHERE tablename = 'something' AND
LEFT_FROM BETWEEN " . $newstart[$crow] . " AND " . $newend[$crow] . " OR
LEFT_TO BETWEEN " . $newstart[$crow] . " AND " . $newend[$crow] . " OR ".
$newstart[$crow] . " BETWEEN " . "LEFT_FROM" . " AND ". " LEFT_TO";
$result = mysqli_query($GLOBALS['Con'], $newsql);
if (!$result) {
echo "Error: " . mysqli_error($GLOBALS['Con']) . "<br>";
}
if (!empty($result)) {
echo "Overlap: ". "Row2 LEFT_FROM: " . $row2['LEFT_FROM'] . " NewStart: " . $newstart[$crow] . " Row2 LEFT_TO: " . $row2['LEFT_TO'] . " Newend: " . $newend[$crow] . "<br>" . "Crow: " . $crow . "<br>" ;
}
}
echo "Crow: " . $crow . "<br>";
$crow++;
}
atempt at array_intersect all variables in arrays are set to 0
$result = mysqli_query($GLOBALS['con'], $select);
$Rows = $result->num_rows;
$Rows2 = $Rows;
$Rows3 = $Rows;
$Rows4 = $Rows;
$Rows5 = $Rows;
$range1 = array();
$range2 = array();
$range3 = array();
$range4 = array();
while ($counter <= $Rows) {
$range1[$crow] = $leftfrom[$add];
$range2[$crow] = $leftto[$add];
$counter++;
$road++;
$crow++;
}
while ($counter2 <= $Rows2) {
$range3[$crow2] = $leftfrom[$add2];
$range4[$crow2] = $leftto[$add2];
$counter2++;
$road3++;
$crow2++;
}
$Combined1 = array();
$Combined1 = array();
while ($counter3 <= $Rows3) {
$Combined1[$crow5] = range($range1[$crow3], $range2[$crow3]);
$Combined2[$crow6] = range($range3[$crow3], $range4[$crow3]);
$crow5++;
$crow6++;
$crow3++;
$counter3++;
}
$check1 = 0;
while ($check1 <= $Rows4) {
$GLOBALS['check2'] = 0;
$Rows6 = $GLOBALS['check2'] + 1;
while ($GLOBALS['check2'] <= $Rows5) {
$results = array_intersect($Combined1[$check1],$Combined2[$Rows6]);
if ($results) {
$start = reset($results);
$end = end($results);
echo "These are overlapping" . "<br>";
echo "Start of overlap: " . $start . " Rows#: " . $check1 . " Bad Row: " . $GLOBALS['check2'];
echo "<br>";
echo "end of overlap: " . $end;
echo "<br>" . $GLOBALS['check2'] ;
$GLOBALS['check2']++;
}else{
echo "<br>" . $check1 . " No duplicates" . "<br>";
$GLOBALS['check2']++;
}
}
$check1++;
}
You don't need a loop in PHP, you can do it entirely by joining the table with itself.
SELECT *
FROM yourTable AS t1
JOIN yourTable AS t2
ON t1.id < t2.id
AND (t1.left_from <= t2.left_to AND t2.left_from <= t1.left_to)
t1.id < t2.id keeps it from treating a row as overlapping with itself (and using < rather than != keeps it from showing the same pair of rows twice). Replace id with the primary key of your table.
To check, if two number ranges overlap, you could use the simple test x1 < y2 AND y1 < x2. This could be combined in a single sql statement.
SELECT
t1.LEFT_FROM as LEFT_FROM_1,
t1.LEFT_TO as LEFT_TO_1,
t2.LEFT_FROM as LEFT_FROM_2,
t2.LEFT_TO as LEFT_TO_2
FROM
t t1, t t2
WHERE
t1.LEFT_FROM < t2.LEFT_TO AND t2.LEFT_FROM < t1.LEFT_TO
This query would return all overlapping ranges.

Converting .Net API to PHP

I have this .Net REST API function modified from the demo for a grid control here: http://gijgo.com/grid/demos/ajax-sourced-data.
However, I am using PHP on the backend.
public JsonResult Get(int? page, int? limit)
{
List<Models.inventory> records;
int total;
using (ApplicationDbContext context = new ApplicationDbContext())
{
var query = context.inventory.Select(p => new Models.inventory
{
id = p.id,
company = p.company,
part = p.part,
year = p.year,
model = p.model,
stock = p.stock,
ic = p.ic,
vin = p.vin,
status = p.status,
bodycolor = p.bodycolor,
condition = p.condition,
comments = p.comments,
miles = p.miles,
price = p.price,
qty = p.qty
});
query = query.OrderBy(q => q.id);
total = query.Count();
if (page.HasValue && limit.HasValue)
{
int start = (page.Value - 1) * limit.Value;
records = query.Skip(start).Take(limit.Value).ToList();
}
else
{
records = query.ToList();
}
}
return this.Json(new { records, total }, JsonRequestBehavior.AllowGet);
}
I have converted the function to PHP but am having difficulty with the pagination because the total records isn't really being sent.
The C# code, filters the data after the query and i'm not sure how to do that with PHP and PostgreSQL.
I also want to return the total number of rows without the limit and offset in the result I suppose I'm going to have to run a 2nd query to return that data,
is that correct or can I do it in another way?
private function GetInventory()
{
$ic=$_request['ic'];
$limit=$_request['limit'];
$offset=$_request['page']-1;
$sql = "SELECT u.id, "
. " (SELECT company FROM urgss.users WHERE id = u.id) AS company, "
. " u.itemname || ' (' || u.part || ')' as part, "
. " u.year, "
. " u.model, "
. " u.stockno AS stock, "
. " u.ic AS ic, "
. " u.vin, "
. " u.status || ' / ' || u.currentstatus AS status, "
. " REGEXP_REPLACE(u.bod_col, '[\[\]]', '', 'g') AS bodycolor, "
. " u.condition, "
. " u.comments, "
. " CASE "
. " WHEN u.miles::integer < 1000 THEN "
. " u.miles::INTEGER * 1000 "
. " ELSE "
. " u.miles::INTEGER "
. " END AS miles, "
. " CASE "
. " WHEN u.rprice > 0 THEN "
. " u.rprice "
. " ELSE "
. " NULL "
. " END AS price, "
. " u.qty "
. "FROM unet u "
. "WHERE ic = '" . $ic. "' "
. "AND year::integer > 0"
. " LIMIT " . $limit . " OFFSET ". ($offset * $limit);
$result = pg_exec($db, $sql);
$rows = pg_fetch_all($result);
echo json_encode($rows);
}
If you remove LIMIT from the query (REMOVE THIS . " LIMIT " . $limit . " OFFSET ". ($offset * $limit);), then there are two options:
Instead of pg_fetch_all you could fetch in a loop and specify the $row_num based on offset and limit:
//get total number of rows
$total = pg_num_rows($result);
//get rows from offset up to limit
$row_num = $offset;
while($row_num < ($offset + $limit) && $rows[] = pg_fetch_assoc($result, $row_num)) {
$row_num++;
}
echo json_encode($rows);
Or pg_fetch_all and slice what you want:
//get total number of rows
$total = pg_num_rows($result);
//get ALL rows
$rows = pg_fetch_all($result);
//get rows from offset up to limit
$rows = array_slice($rows, $offset, $limit);
echo json_encode($rows);
Not sure what new { records, total } does in .NET, but you could return one of these:
return json_encode([$rows, $total]);
//or
return json_encode(['rows' => $rows, 'total' => $total]);

SQL order by date inside WHILE LOOP

I'm having trouble sorting my events by date, as I have event id's in one table and event date in another.
The code is as follows.
$getEventIds = "SELECT * FROM rz6wq_ohanah_registrations WHERE email='".$userEmail."'";
$result = mysqli_query($conn, $getEventIds);
echo '<br />';
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$getEventTitle = "SELECT * FROM rz6wq_ohanah_events WHERE ohanah_event_id=" . $row['ohanah_event_id'] . " ORDER BY date ASC";
$title = mysqli_query($conn, $getEventTitle);
$rowTitle = $title->fetch_assoc();
$originalDate = $rowTitle["date"];
$newDate = date("d-m-Y", strtotime($originalDate));
date_default_timezone_set('Europe/Copenhagen');
$currentDate = date('d/m/Y');
if(strtotime($currentDate) < strtotime($newDate)){
//echo "id: " . $row["ohanah_event_id"] . "<br>";
echo "<div class='eventsTilmeldt'>";
echo "<b>" . utf8_encode($rowTitle["title"]) . "</b><br>";
echo "<br>";
echo "Status: "; if($row["paid"] == 0){echo "<span style='color:red;'>ej betalt</span>";}else{echo "<span style='color:green;'>betalt</span>";}
echo "<br>";
echo "Dato: " . $newDate . "<br>";
echo "Tidspunkt: " . $rowTitle["start_time"] . "<br>";
echo "<br>";
echo "Adresse: " . utf8_encode($rowTitle["adress"]) . "<br>";
echo "By: " . utf8_encode($rowTitle["geolocated_city"]) . "<br>";
echo "Sted: " . utf8_encode($rowTitle["venue"]) . "<br>";
echo "</div>";
echo "<br>";
}else{
echo "";
}
}
} else {
echo "Ingen tilmeldte events.";
}
The issue that it doesen't sort my event's correctly by date. I figure it has something to do with it being inside the while loop where I order by date?
"SELECT * FROM rz6wq_ohanah_events WHERE ohanah_event_id=" . $row['ohanah_event_id'] . " ORDER BY date ASC";
I need to get the event's from another table first, called registrations - inside this table there is no date field.
How can I sort this list by date ?
You can use JOIN instead:
$getEventIds = "SELECT reg.*,event.* FROM rz6wq_ohanah_registrations as reg
JOIN rz6wq_ohanah_events as event ON reg.ohanah_event_id=event.ohanah_event_id
WHERE email='".$userEmail."'
ORDER BY event.date ASC";
Why use two query You can do it in single query
SELECT A.*,B.* FROM rz6wq_ohanah_registrations AS A JOIN
rz6wq_ohanah_events AS B ON A.ohanah_event_id=B.ohanah_event_id WHERE
A.email='".$userEmail."' ORDER BY B.date ASC
$getEventIds = "SELECT * FROM rz6wq_ohanah_registrations AS ROR, z6wq_ohanah_events AS ZOE WHERE ROR.ohanah_event_id = ZOE.ohanah_event_id AND ZOE.email = '" . $userEmail . "' ORDER BY date ROR.ASC";

Output single result of a MySQL Query with PHP not working

My table 'viewlevels' has the following data (among other):
id |title
10 |Cenas
I'm running the SQL query:
SELECT title FROM viewlevels WHERE id=10
Which is returning "Cenas" as expected.
But using the following PHP script, I just get "texto= " , why?
$res = $db->query("SELECT title FROM viewlevels WHERE id=10");
$res->data_seek(0);
while ($row = $res->fetch_assoc()) {
echo " texto= " . $row['title'] . "\n";
};
To see both fields you have to echo those columns:
while ($row = $res->fetch_assoc()) {
echo " id= " . $row['id'] . "\n";
echo " texto= " . $row['title'] . "\n";
};
You don't need to use data_seek in this instance.
$res = $db->query("SELECT title FROM viewlevels WHERE id=10");
while ($row = $res->fetch_assoc()) {
echo " texto= " . $row['title'] . "\n";
}
Will work.

Sub total according to date

i try to solve a problem but did not succeed.
I have a index page and users search. for example
What i want to do is to have subtotal. I mean i want to have a total according to day.
for example user search for 2012-02-22 and 2012-02-23 but i need total for 22 and 23 of month .
To do that: I did this it calculate on t
while ($info = mysql_fetch_array($dbResult)) {
$total+= $info['totalEvents'];
$total2 = 0;
echo "<tr>";
echo "<td><input type=checkbox name='check1' id='check1' value='" . $info['eventCategory'] . "' onclick=recal(" . $info['totalEvents'] . ",this.checked) checked></td>
<label id ='nameID'><td>" . $info['id'] . " " . $info['profileName'] . "</td>";
echo "<td><label id='eventCategory'>" . $info['eventCategory'] . "</td>";
echo "<td><label id='totalEvents'>" . $info['totalEvents'] . "</label></td>";
if ($info['Date'] != $previousDate) {
echo "<td><b>" . $info['Date'] . "</b></td></tr>";
$total2++;
} else {
echo "<td></td>";
}
$previousDate = $info['Date'];
}
but it calculates like that
finally i come to this
but i calculates wrongly
else if ($_POST['group1'] == 'VideoFinish') {
$dbResult = mysql_query("SELECT la.id,st.profileName, la.totalEvents,la.Date,ft.eventCategory FROM videofinish la INNER JOIN profiles st ON st.id=la.id INNER JOIN eventcategory ft ON ft.id = la.eventCategoryID where Date BETWEEN '" . $startDate . "' and '" . $endDate . "'");
if (isset($_POST['checkPremium'])) {
$dbResult = mysql_query("SELECT la.id,st.profileName, la.totalEvents,la.Date,ft.eventCategory FROM videofinish la INNER JOIN profiles st ON st.id=la.id and st.isPremium=1 INNER JOIN eventcategory ft ON ft.id = la.eventCategoryID where Date BETWEEN '" . $startDate . "' and '" . $endDate . "'");
}
$previousDate = '';
$totalDay = 0;
while ($info = mysql_fetch_array($dbResult)) {
$total+= $info['totalEvents'];
echo "<tr>";
echo "<td><input type=checkbox name='check1' id='check1' value='" . $info['eventCategory'] . "' onclick=recal(" . $info['totalEvents'] . ",this.checked) checked></td>
<label id ='nameID'><td>" . $info['id'] . " " . $info['profileName'] . "</td>";
echo "<td><label id='eventCategory'>" . $info['eventCategory'] . "</td>";
echo "<td><label id='totalEvents'>" . $info['totalEvents'] . "</label></td>";
if ($info['Date'] != $previousDate && $info['Date'] != $previousDate) {
echo "<td><b>" . $info['Date'] . "</b></td></tr>";
echo "<b>".$info['Date']."</b>:";
echo $totalDay."<br />";
} else {
echo "<td></td>";
}
$previousDate = $info['Date'];
$totalDay += $info['totalEvents'];
}
echo "<td><b id='total'>" . $total . "</b></td>";
}
Try this .. i put comments in the code for your understanding.
// initialize counter and previous date
$totalDay = 0;
$previousDate = NULL;
// we need to change the loop structure so that the loop code is executed
// a last time when there are no further rows. Otherwise, we would have
// no total on the last day!
while (true) {
// we break the loop when there are no further rows after sub total is printed
$info = mysql_fetch_array($dbResult);
// when date changes, print total line and reset counter
if ( $previousDate <> NULL &&
( !isset($info['Date']) || $info['Date'] <> $previousDate ) ) {
echo '<tr>';
// no checkbox
echo '<td></td>';
// label in second cell
echo '<td><b>Total for day ' . $previousDate .'</b></td>';
// total in last cell
echo '<td colspan="4" align="right"><b>' . $totalDay . '</b></td>';
echo '</tr>';
// day has changed, so reset the sub total for next day
$totalDay = 0;
}
// now if the have no further rows, break the loop
if ($info == false)
break;
// add current value to sub total
$totalDay += $info['totalEvents'];
echo "<tr>";
echo "<td><input type=checkbox name='check1' id='check1' value='" . $info['eventCategory'] . "'
onclick=recal(" . $info['totalEvents'] . ",this.checked) checked></td>";
echo "<label id ='nameID'><td>" . $info['id'] . " " . $info['profileName'] . "</td>";
echo "<td><label id='eventCategory'>" . $info['eventCategory'] . "</td>";
echo "<td><label id='totalEvents'>" . $info['totalEvents'] . "</label></td>";
echo "<td>";
// when date changes (also on first day), print date
if ($info['Date'] <> $previousDate) {
echo "<b>" . $info['Date'] . "</b>";
}
echo "</td>";
echo "</tr>";
// remember current date for next row calculation
$previousDate = $info['Date'];
}
You can do GROUP BY your_date_field WHERE your_date_field in (22,23)` in your mysql statement.
try this query
select * from table
GROUP BY date_column
WHERE date_column between "2001-01-05" and "2001-01-10"

Categories