This question already has an answer here:
How Can Calculate Credits,Debits & Balance in the general ledger?
(1 answer)
Closed last year.
I am trying code in php with mysql and I want to calculate running balance based on the type of transaction. My database table is as per below
id | amt | type | date
----+---------+----------+-----------
1 | 70000 | Cr | 01-01-2022
2 | 8000 | Dr | 01-01-2022
3 | 60000 | Cr | 02-01-2022
4 | 50000 | Dr | 02-01-2022
5 | 90000 | Cr | 03-01-2022
6 | 28000 | Dr | 03-01-2022
And I want the result as per below, if type = Cr then ADD and if type = Dr then SUBTRACT and auto calcuate running BALANCE where initial value to be ZERO
id | Dr | Cr | date | balance
----+----------+---------+-------------+----------
1 | 0 | 70000 | 01-01-2022 | 70000
2 | 8000 | 0 | 01-01-2022 | 62000
3 | 0 | 60000 | 02-01-2022 | 122000
4 | 50000 | 0 | 02-01-2022 | 72000
5 | 0 | 90000 | 03-01-2022 | 162000
6 | 28000 | 0 | 03-01-2022 | 134000
The following is the PHP script I'm currently using
<table>
<tr><th>Date</th><th>IN</th><th>OUT</th><th>Balance</th></tr>
<?php
$conn=mysqli_connect("details hidden");
$sql="SELECT * FROM table_name WHERE type IN ('Dr', 'Cr') ORDER BY date DESC";
$query=mysqli_query($conn, $sql);
while ($row=mysqli_fetch_array($query)) {
echo '<tr>';
echo '<td>'.$newdate = date('d-m-y', strtotime($row['date'])).'</td>';
if ($row['type']==Dr){
echo '<td>'.$row['amt'].'</td>';
echo '<td></td>';}
elseif ($row['type']==Cr){
echo '<td></td>';
echo '<td>'.$row['amt'].'</td>';}
else {
echo '<td></td>;
echo '<td></td>;}
echo '</tr>';
}
?>
</table>
Any help would be helpful.
You can use the sum window function to get the result you want:
select id,
case when `type` = 'Dr' then `amt` else 0 end as Dr,
case when `type` = 'Cr' then `amt` else 0 end as Cr,
date,
sum(case when `type` = 'Dr' then -`amt` when `type` = 'Cr' then `amt` end) over(order by date rows unbounded preceding) as balance
from table_name;
Fiddle
Related
Assalammualaikum..
I have database like this:
name | subjects | score
B | math | 70
B | math | 80
B | scien | 90
A | math | 80
And I have query like this:
$query = mysqli_query($db,"SELECT name, subject, score
(
CASE subject WHEN #curSubject
THEN #curRow := #curRow +1
ELSE #curRow :=1 AND #curSubject:= subject END
) AS rank
FROM table GROUP BY name,score ORDER BY name, score desc");
If I Select on SQL output from that query just like this:
name | subjects | score | rank
B | math | 80 | 1
B | math | 70 | 2
B | scien | 90 | 1
A | math | 80 | 1
My problem is, when I will echo using looping php code like this:
while ($array = mysqli_fetch_array($query)){
echo $array['rank']'';
}
output:
rank | rank (not like this)
1 | 1
1 | 2
1 | 1
1 | 1
How can the value rank be echoed? Thank you
Wassalammualaikum..
This query will take around 5 seconds to complete. I mean when I refresh or navigate to the page it will take 5 seconds to complete the browser loading and to display the total counts.
Here is what I want to achieve, FIRST is to get the MAX value of the systemID (ID) based on the empID.
But before the First query ends I made another query the will get the row where the empID has a JUMP value on the eStatus col.
This is to compare the year difference of the latest data startDate of the empID and to his previous JUMP endDate.
Here is my table
---|-------|-----------|------------|---------
ID | empID | startDate | endDate | eStatus
---|-------|-----------|------------|---------
1 | 10 | 2001-1-31 | 2001-12-31 |
2 | 10 | 2002-1-31 | 2002-12-31 |
3 | 22 | 2001-1-31 | 2001-12-31 |
4 | 10 | 2003-1-31 | 2003-12-31 | JUMP
5 | 10 | 2004-1-31 | 2004-12-31 |
6 | 22 | 2002-1-31 | 2002-12-31 | JUMP
7 | 10 | 2005-1-31 | 2005-12-31 |
8 | 22 | 2003-1-31 | 2003-12-31 |
9 | 22 | 2004-1-31 | 2004-12-31 |
10 | 10 | 2006-1-31 | 2006-12-31 | JUMP
11 | 10 | 2007-1-31 | 2007-12-31 |
12 | 10 | 2008-1-31 | 2008-12-31 |
13 | 10 | 2009-1-31 | 2009-12-31 | JUMP
14 | 10 | 2010-1-31 | 2010-12-31 |
15 | 10 | 2011-1-31 | 2011-12-31 |
the First query will get the max ID by group of empID.
---|-------|-----------|------------|---------
ID | empID | startDate | endDate | eStatus
---|-------|-----------|------------|---------
15 | 10 | 2011-1-31 | 2011-12-31 |
9 | 22 | 2004-1-31 | 2004-12-31 |
the Second query will get the empID row that has a JUMP data on the eStatus Col
---|-------|-----------|------------|---------
ID | empID | startDate | endDate | eStatus
---|-------|-----------|------------|---------
4 | 10 | 2003-1-31 | 2003-12-31 | JUMP
6 | 22 | 2002-1-31 | 2002-12-31 | JUMP
10 | 10 | 2006-1-31 | 2006-12-31 | JUMP
13 | 10 | 2009-1-31 | 2009-12-31 | JUMP
6 | 22 | 2002-1-31 | 2002-12-31 | JUMP
Now I can compute the date difference from startDate of 1st query and enddate of 2nd query. If it is greater than 2 the it will count to my final count.
THANK YOU SO MUCH IN ADVANCE and KEEP SAFE.
Here is my code:
<?php
$counterA= 0;
$counterB= 0;
$finalCount = 0;
$result = mysqli_query($con,"SELECT empID,endDate FROM tablerecord
WHERE ID IN (SELECT MAX(ID) FROM tablerecord GROUP BY empID)");
while ($row=mysqli_fetch_assoc($result )) {
$counterA++; //count how many result based on the above query
$emp_max = $row['empID']; //Get emp ID based on max ID
endDate_result = $row['endDate']; //Get endDate based on max ID
$resultPrevious=mysqli_query($con,"SELECT empID,startDate FROM tablerecord
WHERE empID = '$emp_max' AND eStatus = 'JUMP' ");
while ($rowPrevious=mysqli_fetch_assoc($resultPrevious)) {
$counterB++; //count how many result based on the above query
$dateA=date_create($rowPrevious['startDate']);
$dateB=date_create($endDate_result);
$diff2=date_diff($dateA,$dateB);
$numLenght = $diff2->y;
if ($numLenght > 2) {
$finalCount++;
}
}
}
echo $counterA;
echo "<br>";
echo $counterB;
echo "<br>";
echo $finalCount;
?>
if I understand correctly, what you want is to select all data that have eStatus value jump.
why not simply SELECT empID,startDate FROM tablerecord WHERE empID IN(SELECT MAX(ID) FROM tablerecord) AND eStatus = 'JUMP'?
or, if you want the unique value of empID, SELECT empID,startDate FROM tablerecord WHERE empID IN(SELECT DISTINCT(ID) FROM tablerecord) AND eStatus = 'JUMP'
all my query above will not produce any result
you might want to try multiple select in your query for a crude way to get it all in one go
select * from tablerecord where empID in(SELECT empID FROM tablerecord WHERE ID IN (SELECT MAX(ID) FROM tablerecord group by empID)) and eStatus = 'JUMP'
in this way, you only query the DB one time and the rest can be done with your PHP code
I would use this query to get all needed data :
# Get first and last jump for each empID
SELECT *
FROM tablerecord t1
WHERE t1.ID = (
SELECT MIN(t2.ID)
FROM tablerecord t2
WHERE t1.empID==t2.empID
) or t1.ID = (
SELECT MAX(t3.ID)
FROM tablerecord t3
WHERE t1.empID==t3.empID
)
And then some PHP to run through, comparing each pairs
$result = mysqli_query($con,"the_previous_query....");
$row_to_compare_with =false;
while ($row=mysqli_fetch_assoc($result )) {
if ($row_to_compare_with == false) {
$row_to_compare_with = $row;
} else {
// Compare $row_to_compare_with with $row, both having same empId
// do your thing here...
$row_to_compare_with = false;
}
}
please assume this as the table
tablename- schemeOverview
| slno |schemename | amount| date2 | date3 | date4 ...daten |
|---------|-----------|-------|-------|-------|-------|----------|
| 1 | Cell | 1000 | DUE | DUE | | |
| 2 | Cell | 1000 | PAID | PAID | | |
| 3 | Cell | 1000 | DUE | DUE | DUE | |
| 4 | Cell | 1000 | PAID | PAID | | |
| 5 | Cell | 1000 | DUE | DUE | | |
I am trying to count the number of fields that have value as 'PAID' .
for example the count of PAID for slno-2 should be 2.
the number of date columns varies per table but I have the count of date columns for a table.So a better option would be to check all fields of the specified row(slno)
you can use this code
SELECT slno,count(*) AS paid
FROM schemeOverview
WHERE 'PAID' IN (date2, date3, date4,...,daten)
Well after a lot of brain drain I came up with this and It works!
$paidCount=0;
$sql2 = "SELECT * FROM " .$scheme_name. " WHERE slno = " .$recBookNo;
$result2 = mysqli_query($conn,$sql2);
if($result2)
{
while ($row19 = $result2->fetch_assoc())
{
foreach ($row19 as $key => $value)
{
if(($value)=='PAID')
{
$paidCount++;
}
}
}
}
You can use count()
SELECT count(date2) as cd2 FROM schemeOverview WHERE date2 = "PAID"
This will store the value into cd2, in this case 2
I have a MySQL table like this:
| rsid | rsuser | rsintime | rsouttime | rsroom |
| ---- | ------- | ---------------- | ---------------- | ------ |
| 1 | Nick S | 10/14/2014 11:17 | 10/14/2014 12:18 | 1 |
| 2 | Mike G | 10/15/2014 10:18 | 10/15/2014 11:19 | 1 |
| 3 | Chuck M | 10/14/2014 21:56 | 10/14/2014 22:56 | 1 |
| 4 | Jake B | 10/26/2014 22:14 | 10/26/2014 23:15 | 1 |
My PHP code is:
<?php
$con=mysqli_connect("0.0.0.0","roomapp","hi","roomapp");
$testschedulesql = "SELECT (NOW() > rsintime AND NOW() < rsouttime) as res_rm from raRmSchedule";
$testscheduleqry = mysqli_query($con, $testschedulesql);
$testschedule = mysqli_num_rows($testscheduleqry);
$testscheduletext = mysqli_fetch_array($testscheduleqry);
echo $testschedule;
if($testschedule > 0){
echo 'Busy';
}
else{
echo 'Not';
}
?>
However, $testschedule always returns the total rows. I want it to return only rows where the current time is within an in/out time. What am I doing wrong?
You need a where clause:
SELECT rm.*
from raRmSchedule
WHERE (NOW() > rsintime AND NOW() < rsouttime)
To count the number of rows:
SELECT COUNT(*)
from raRmSchedule
WHERE (NOW() > rsintime AND NOW() < rsouttime)
This returns one row with one column. It will be 0 if there are no matches.
Your version returns one row for each row in the table. There will be one column with a value of 0 or 1, depending on whether the condition matches.
Of course it will give you all rows, as what you are selecting is the boolean value of an expression.
I think what you want is giving the query a WHERE clause to filter the time you're needing.
Something like
Select * from raRMSchedule where (now() > rsintime and now() < rsouttime).
I have the following sql which selects the most recurring row first based on the column "reported"
$datan = mysql_query("
SELECT *, COUNT(reported) AS ct
FROM profile_reports
WHERE open = '1'
GROUP BY reported
ORDER BY ct DESC
LIMIT 1
") or die(mysql_error());
I want my sql to also check which 'reporter' (each is a number associated with a user) has the best percentage of useful reports, which is determined this way:
((raction > 0 AND raction < 99 AND open = '0' AND reporter = 'reporter') / (reporter = 'reporter' AND open = '0')) * 100
...and show the rows with highest percentage first. It's a little tricky because no initial reporter is set.
Here's a sample table:
+----+----------+----------+-------+----------+
| id | reporter | reported | open | raction |
+----+----------+----------+-------+----------+
| 1 | 24 | 26 | 0 | 3 |
| 2 | 24 | 23 | 0 | 0 |
| 3 | 24 | 29 | 1 | |
| 4 | 12 | 29 | 0 | 4 |
| 5 | 12 | 29 | 1 | |
| 6 | 24 | 21 | 1 | 0 |
+----+----------+----------+-------+----------+
I want it to see that there are more reports about user 29(column: reported), then check which reporting user(column: reporter) has the best percentage (based on the line of code above), in this case user 12, and display their report
Its actually pretty easy in just take the sums of your conditions and divide. In order to get the "Reported" correctly you'll need to use an inline view to find the highest report.
SELECT pr.*,
( Sum(pr.raction > 0
AND pr.raction < 99
AND pr.open = '0'
AND pr.reported = t.reported) / Sum(pr.reported = t.reported
AND pr.open = '0') ) * 100 AS
usefull
FROM profile_reports pr,
(SELECT reported
FROM profile_reports
WHERE open = '1'
GROUP BY reported
ORDER BY Count(reported) DESC
LIMIT 1) t
GROUP BY reporter
ORDER BY usefull DESC
LIMIT 1
demo
Output
| ID | REPORTER | REPORTED | OPEN | RACTION | USEFULL |
-------------------------------------------------------
| 4 | 12 | 29 | 0 | 4 | 100 |
I haven't done everything for you. You will have to decide what to do if the divisor is zero
Note in just about everything but MySQL you would need to use CASE
SUM ( CASE WHEN raction > 0 AND .... THEN 1 ELSE 0 END) / ....