This is the data am having in my table named rent
id date stud_id paid balance
18 10-2016 94 15000 15000
19 10-2016 94 10000 5000
20 10-2016 96 25000 5000
21 10-2016 96 5000 0
here i want to get last inserted stud_id balance but am getting the first one.
my code looks like this
public function rent_outstanding($hos,$dt)
{
$this->db->select('student_hostel.*,rent.balance,rent.paid');
$this->db->join('rent','rent.stud_id=student_hostel.id');
$this->db->where('status!=','G');
$this->db->where('status!=','R');
$this->db->where('hostel',$hos);
$this->db->where('rent.date',$dt);
$this->db->select_sum('paid');
$this->db->group_by('stud_id');
$query=$this->db->get('student_hostel');
return $query;
}
my student_hostel table looks like this
id first_name last_name stud_id admit_date hostel class room bed status
94 ss ff PHBH00094 01-10-2016 12 16 115 501A P
96 maltu uv PHBH00096 01-10-2016 12 16 115 501C p
am getting my result like this
SI.No STUDENT ID NAME RENT PAID BALANCE
1 PHBH00094 Ss 30000 25000 15000
2 PHBH00096 Maltu 30000 30000 5000
i want to get my result like this
SI.No STUDENT ID NAME RENT PAID BALANCE
1 PHBH00094 Ss 30000 25000 5000
2 PHBH00096 Maltu 30000 30000 0
You need to specify somewhere to take the max of ID from rent table.
This query should give you that.
select stud_id ,first_name, paid, balance from rent rt, student_hostel s where
hostel='$hosr' and ent.date='$dt' and id = (select max(id) from rent r where r.stud_id = rt.stud_id) and status!= 'G' and status!= 'R'
Add date to inner query if you need balance of that date id = (select max(id) from rent r where r.stud_id = rt.stud_id and r.date='$dt')
For Codeignitor you can write the query directly:
$sql = "select stud_id ,first_name, paid, balance from rent rt, student_hostel s where hostel=? and ent.date=? and id = (select max(id) from rent r where r.stud_id = rt.stud_id) and status!= 'G' and status!= 'R'";
$this->db->query($sql, array($hosr, $dt));
More info here: https://www.codeigniter.com/userguide3/database/queries.html#query-bindings
Related
I have two tables Order and Transaction
Order Table
id
OrderId
TransId
OrderDate
1
54
11551
01-12-2021
2
55
11552
02-12-2021
3
56
11553
02-12-2021
4
57
11554
05-12-2021
5
58
11555
08-12-2021
6
59
11556
09-12-2021
Transaction Table
id
TransId
OrderId
PaymentMethod
Amount
1
11551-1
54
Cash
1000
2
11552-1
55
Cash
500
3
11552-2
55
Card
200
4
11553-1
56
Cash
500
5
11553-2
56
Card
200
6
11553-3
56
UPI
100
Here we have 3 Transaction methods Cash, Card and UPI.
I want to get total Amount collected using Cash as PaymentMethod done for period 01-12-2021 to 08-12-2021 in orderDate of Order Table
select t.paymentMethod, sum(t.amount) from tbl_order o
inner join tbl_transaction t on o.orderId = t.orderId
where t.paymentMethod = 'CASH' and o.orderDate between start_date and end_date
group by t.paymentMethod;
write an sql to generate the report for employee dataset with give condition if average age >35 then states value is ok else notok dataset
id name age dept salary
1 tt 51 it 4000
2 kk 56 it 6000
3 mm 45 sales 7000
4 kk 25 sales 9000
5 op 24 hr 4000
6 op 24 hr 8000
output
dept avgage states
it 53.5 ok
sales 35 ok
hr 24 notok
Use this query.
SELECT a.dept,
a.avgage,
CASE
WHEN a.avgage >= 35 THEN 'ok'
ELSE 'notok'
END states
FROM (SELECT dept,
Avg (age) avgage
FROM employee
GROUP BY dept) a
ORDER BY avgage DESC;
Note: Please show some effort to understand and write a query on your own.
Here am having two tables namely rent and student_hostel.the rent table looks like this
id date stud_id paid balance
18 10-2016 94 15000 15000
19 10-2016 94 10000 5000
20 10-2016 96 25000 5000
21 10-2016 96 5000 0
my student_hostel table looks like this..
id first_name last_name stud_id admit_date hostel class room bed status
94 ss ff PHBH00094 01-10-2016 12 16 115 501A P
96 maltu uv PHBH00096 01-10-2016 12 16 115 501C p
In order to get the last inserted stud_id's balance i used my code like this,
public function rent_outstanding($hos,$dt)
{
$sql = "select s.stud_id ,s.admit_date ,s.class,first_name,sum(paid) as rt_paid,balance,rt.stud_id
from student_hostel s, rent rt where s.id=rt.stud_id and hostel=? and rt.date=?
and rt.id = (select max(id) from rent r where r.stud_id = rt.stud_id and r.date='$dt')
and status!= 'G' and status!= 'R' GROUP BY rt.stud_id";
$query=$this->db->query($sql, array($hos, $dt));
return $query;
}
the problem am facing here is i was not able to sum the values comes under the paid columns of same stud_id.
the output am getting is like this
SI.No STUDENT ID NAME RENT PAID BALANCE
1 PHBH00094 Ss 30000 10000 5000
2 PHBH00096 Maltu 30000 5000 0
the desired output i need to get is like this
SI.No STUDENT ID NAME RENT PAID BALANCE
1 PHBH00094 Ss 30000 25000 5000
2 PHBH00096 Maltu 30000 30000 0
Your final solved query is :
select s.stud_id ,s.admit_date ,s.class,first_name,sum(paid) as rt_paid,
(select r.balance from rent r where r.stud_id = rt.stud_id and r.date='$dt' order by r.id desc limit 1) as balance ,rt.stud_id
from student_hostel s join rent rt on s.id=rt.stud_id where hostel=? and rt.date=?
and status!= 'G' and status!= 'R' GROUP BY s.stud_id
I have removed this line in your existing query rt.id = (select max(id) from rent r where r.stud_id = rt.stud_id and r.date='$dt')
your (select max(id) from rent r where r.stud_id = rt.stud_id and r.date='$dt') means all time getting only one last row rt.id like 19 (for PHBH00094) or 21 (for PHBH00096).
that's why you getting all time one last calculation.
Here I want to get the previous row balance value in to my field.
The last id of customer_id '16' of balance is 200, but I want to get the previous ids value in to the field and this is my table
id order_id customer_id amount actual_amount paid_amount balance type
25 11 16 100.00 50.00 50.00 Cash
26 12 16 200.00 100.00 100.00 Cash
27 13 16 150.00 100.00 50.00 Cash
28 14 16 300.00 250.00 50.00 Cash
29 14 16 170.00 100.00 70.00 Cash
30 15 16 100 170.00 70.00 100.00 Cash
31 16 16 400 500.00 300.00 200.00 Cash
this is my model
public function order_balance($order_code)
{
$this->db->join('services','payment.customer_id=services.customer_id','left');
$this->db->select('payment.*,payment.balance,payment.actual_amount,payment.customer_id');
$this->db->order_by('payment.id','desc');
$query = $this->db->get_where('payment',array('code' => $order_code));
return $query->previous_row();
}
This is my control:
public function final_payment($order_code)
{
$data['active_mn']='';
$data['result'] = $this->Account_model->order_balance($order_code);
$this->load->view('final_payment',$data);
}
My services table looks like this:
id code customer_id particulars
11 ORD00011 16 phone
12 ORD00012 16 gdf
13 ORD00013 16 ghgfh
14 ORD00014 16 tv
15 ORD00015 16 ghfg
16 ORD00016 16 tv
17 ORD00017 16 gdfg
18 ORD00018 16 desk
19 ORD00019 16 gdf
My result should be like this:
id order_id customer_id amount actual_amount paid_amount balance type
31 16 16 400 500.00 300.00 100.00 Cash
One option here would be to do a self join with the payment table, joining on the customer_id and order_id columns. You can add another join function call and then use the result in your select. The following solution uses a raw query since Codeigniter does not seem to tolerate arithmetic in the join condition:
public function order_balance($order_code)
{
$this->db->query("SELECT p1.*, p2.balance AS previous_balance FROM payment p1 INNER JOIN payment p2 ON p1.order_id = p2.order_id + 1 AND p1.customer_id = p2.customer_id LEFT JOIN services s ON p1.customer_id = s.customer_id ORDER BY p1.id DESC");
$query = $this->db->get_where('p1', array('code' => $order_code));
return $query->previous_row();
}
The query has the form:
SELECT p1.*, p2.balance AS previous_balance
FROM payment p1 INNER JOIN payment p2
ON p1.order_id = p2.order_id + 1 AND
p1.customer_id = p2.customer_id
LEFT JOIN services s
ON p1.customer_id = s.customer_id
ORDER BY p1.id DESC
There are lots of ways of writng this. Here's one way. I don't know codeigniter, so you'll have to reverse engineer it...
SELECT a.id
, a.order_id
, a.customer_id
, a.amount
, a.actual_amount
, a.paid_amount
, b.balance
, a.type
FROM
( SELECT x.*
, MAX(y.id) prev
FROM payment x
JOIN payment y
ON y.id < x.id
AND y.customer_id = x.customer_id
GROUP
BY x.id
) a
JOIN payment b
ON b.id = a.prev
ORDER
BY id DESC LIMIT 1;
In MySql I need to select top student in every class in a school in termid=10 to get discount for next term enrollment .
Please notice that total is not in table(I put in below for clearing problem)
I have this workbook table for all students workbook:
id studentid classid exam1 exam2 total termid
1 2 11 20 40 60 10
2 1 22 40 20 60 10
3 4 11 40 20 60 10
4 5 33 10 60 70 10
5 7 22 10 40 50 10
6 8 11 10 30 40 10
7 9 33 20 45 65 10
8 11 11 null null null 10
9 12 54 null null null 02
10 13 58 null null null 02
1st challenge is : exam1 and exam2 are VARCHAR and total is not in table (as i explained).
2nd challenge is : as you can see in id=8 std #11 has not numbers
3rd challenge is : may be two students have top level so they must be in result.
I need result as :
id studentid classid exam1 exam2 total termid
1 2 11 20 40 60 10
3 4 11 40 20 60 10
4 5 33 10 60 70 10
2 1 22 40 20 60 10
i have this query but not work good as i mention.
SELECT DISTINCT id,studentid,classid,exam1,exam2,total,termid ,(CAST(exam1 AS DECIMAL(9,2))+CAST(exam2 AS DECIMAL(9,2))) FROM workbook WHERE ClassId = '10';
You can get the total for the students by just adding the values (MySQL will convert the values to numbers). The following gets the max total for each class:
select w.classid, max(coalesce(w.exam1, 0) + coalesce(w.exam2, 0)) as maxtotal
from workbook w
group by w.classid;
You can then join this back to the original data to get information about the best students:
select w.*, coalesce(w.exam1, 0) + coalesce(w.exam2, 0) as total
from workbook w join
(select w.classid, max(coalesce(w.exam1, 0) + coalesce(w.exam2, 0)) as maxtotal
from workbook w
group by w.classid
) ww
on w.classid = ww.classid and (coalesce(w.exam1, 0) + coalesce(w.exam2, 0)) = ww.maxtotal;
Another approach is to join the table with itself. You find out the max for each class and then join all students of this class which match the class max:
max for each class (included in the final statement already):
SELECT classid, MAX(CAST(exam1 AS UNSIGNED) + CAST(exam2 AS UNSIGNED)) as 'maxtotal'
FROM students
WHERE NOT ISNULL(exam1)
AND NOT ISNULL(exam2)
GROUP BY classid
The complete statement:
SELECT s2.*, s1.maxtotal
FROM (SELECT classid, MAX(CAST(exam1 AS UNSIGNED) + CAST(exam2 AS UNSIGNED)) as 'maxtotal'
FROM students
WHERE NOT ISNULL(exam1)
AND NOT ISNULL(exam2)
GROUP BY classid) s1
JOIN students s2 ON s1.classid = s2.classid
WHERE s1.maxtotal = (CAST(s2.exam1 AS UNSIGNED) + CAST(s2.exam2 AS UNSIGNED));
SQL Fiddle: http://sqlfiddle.com/#!2/9f117/1
Use a simple Group by Statement:
SELECT
studentid,
classid,
max(coalesce(exam1,0)) as max_exam_1,
max(coalesce(exam2,0)) as max_exam_2,
sum(coalesce(exam1,0) + coalesce(exam2,0)) as sum_exam_total,
termid
FROM
workbook
WHERE
termid=10
GROUP BY
1,2
ORDER BY
5
Try something like this:
SELECT id,studentid,classid,exam1,exam2,(CAST(exam1 AS DECIMAL(9,2))+CAST(exam2 AS DECIMAL(9,2))) AS total,termid FROM `workbook` WHERE ((CAST(exam1 AS DECIMAL(9,2))+CAST(exam2 AS DECIMAL(9,2)))) > 50
Thanks all my friends
I think combine between 2 answer in above is best :
SELECT s2.*, s1.maxtotal
FROM (SELECT ClassId, MAX(
coalesce(exam1,0)+
coalesce(exam2,0)
) as 'maxtotal'
FROM workbook
WHERE
(
termid = '11'
)
GROUP BY ClassId) s1
JOIN workbook s2 ON s1.ClassId = s2.ClassId
WHERE s1.maxtotal = (
coalesce(exam1,0)+
coalesce(exam2,0)
) AND (s1.maxtotal >'75');
last line is good for s1.maxtotal=0 (some times student scores have not be entered and all equals 0 so all will shown as best students) or some times we need minimum score (to enroll in next term).
So thanks all