select distinct sumof from mysql query with having - php

table structure
=====================================================================
id |fee_amount|fee_paid|fee_type|fee_user|date | Fee_for
=====================================================================
1 | 2000 | 500 | REG | 105 | 01.02.2017 | FEB
-----------------------------------------------
2 | 2000 | 1000 | REG | 105 | 03.02.2017 | FEB
-----------------------------------------------
3 | 2000 | 500 | REG | 105 | 04.02.2017 | FEB
-----------------------------------------------
4 | 1000 | 500 | FEE | 105 | 10.03.2017 | MAR
-------------------------------------------------------------
5 | 1000 | 500 | FEE | 105 | 11.03.2017 | MAR
--------------------------------------------------------------
6 | 1000 | 1000 | FEE | 105 | 13.03.2017 | APR
From the above I am saving the fee paying details
one student is paid the amount as partially on the above values
using this I need to get the total fees and total paid fees and the balance need to pay
for this I used
SELECT SUM(fee_amount) as fee, SUM(fee_paid) as paid ,fee_type
FROM tbl_fee A WHERE fee_user='105'
group by fee_type
having SUM(fee_amount)!=(SUM(fee_paid)
But its getting
6000 | 2000 | REG
2000 | 1000 | FEE
I need to get
2000 | 2000 | REG
1000 | 1000 | FEE

Just use this query to get the result that you need
SELECT fee_amount as fee, SUM(fee_paid) as paid ,fee_type FROM tbl_fee A WHERE fee_user='105' group by fee_type

If you do not want to sum the fee_amount field, then simply do not sum it up, but either include it in the group by clause or use the any_value() function to make your query compliant with the sql standard:
SELECT fee_amount as fee, fee_type, SUM(fee_paid) as paid
FROM tbl_fee A
WHERE fee_user='105'
group by fee_type, fee_amount
Obviously, these solutions assume that fee_amount is the same within a fee_type for all users. If the fee_amount can be different within a fee type and a user, then you need to specify how to handle such situations.

Related

How to get a row position using eloquent

I have a leaderboard which shows the top people who have had the most sales.
It's simple. It just gets the top 25 and displays them
$user = \App\User::orderBy('sales', 'desc')
->take(25)
->get();
So that could end up with
+-------+-------------------+
| pos |user_id| sales |
----------------------------|
| 1 | 1 | 1,293 |
| 2 | 99 | 1,093 |
| 3 | 45 | 985 |
| 4 | 948 | 900 |
| 5 | 39 | 889 |
| 6 | 29 | 887 |
+---------------------------+
Now how can I get the position of the user who is viewing the leaderboard if they are not in the top 25?
If the user id 219 is at the position 935 I want to display something like this at the end
+-------+-------------------+
| pos |user_id| sales |
|---------------------------|
| 935 | 219 | 87 |
+---------------------------+
How is this possible to do efficiently without counting up to the user? (As there are thousands of users)
I suppose you have current user data. So, you don't have to query database to get current user id or sales. So, the main problem is to find count of users who have more sales than current.
So, you need a query like
SELECT COUNT(*) as pos FROM your_table WHERE sales > %current_user_sales%
Translate it to laravel query and add 1 when ouptutting.

Grouping MySQL Data and Formatting with PHP and CSS

FYI, I am using PHP and MySQL.
I am working on converting our spreadsheet staff rota to a more interactive online rota system.
I can get all the functions of the rota system fine, but when it comes to formatting it to make it clear of the departments and roles within each department, it is not so obvious.
I dont want to have to create a call to the database for each department and each role within the departments, but am stumped as to how to it to group the results and then output the results correctly and with the formatting I would like.
I do understand that this may be a very vague explanation of what I am trying to get to happen, and feel free to ask as many questions as you like.
I hope I make sense :-)
Have a great day
MySQL Data
ID | Name | Dept | Role
---|--------|------|------
1 | John | 1 | 2
2 | Steve | 1 | 2
3 | Colin | 1 | 3
4 | Trevor | 1 | 3
5 | Nigel | 2 | 4
6 | Gary | 2 | 5
Desire page/table format
STAFF | ..
-------|---
John | ..
Steve | ..
-------|---
Colin | ..
Trevor | ..
-------|---
TOT D1 | ..
-------|---
Nigel | ..
-------|---
Gary | ..
-------|---
TOT D2 | ..
If you want to get the values for each employee and the sum by department you can use the WITH ROLLUP modifier of the GROUP BY clause with adds extra rows with the totals by each value of the grouped columns.
Supposing that you want to show the salary:
select coalesce(name,concat('Total D',Dept)) as Name, sum(Salary) as Salary
from Staff
group by Dept, name with rollup
having coalesce(Dept,0)!=0
Results:
| Name | Salary |
|----------|--------|
| Colin | 80000 |
| John | 100000 |
| Steve | 120000 |
| Trevor | 40000 |
| Total D1 | 340000 |
| Gary | 60000 |
| Nigel | 50000 |
| Total D2 | 110000 |
The HAVING condition if for excluding the final row with the grand total, if you want that row you have to change a bit the COALESCE() to get the proper description:
select coalesce(name,concat('Total D',Dept),'Grand total') as Name, sum(Salary) as Salary
from Staff
group by Dept, name with rollup
Results:
| Name | Salary |
|-------------|--------|
| Colin | 80000 |
| John | 100000 |
| Steve | 120000 |
| Trevor | 40000 |
| Total D1 | 340000 |
| Gary | 60000 |
| Nigel | 50000 |
| Total D2 | 110000 |
| Grand total | 450000 |

Find the total sum of class fees based on the class students enrolled over specific years using mysql or php

I am calculating for the total payments that are made by each class and by the student in a class he or she has ever been enrolled in, depending on the Academic Year.
Now the Student Class Table below has two students, the student with Student ID=0001 has been enrolled in two classes in two different years Class ID = 1, Year=2013 and Class ID=2, Year=2014.
However the student with Student ID=0002 only enrolled in one class and he left the school. Another student was enrolled in class with
Class ID = 1 in Year=2014
Student Class Table
| Student ID | Class ID | Year |
| 0001 | 1 | 2013 |
| 0002 | 1 | 2013 |
| 0003 | 1 | 2014 |
| 0001 | 2 | 2014 |
Below is the amount assigned to each student for each class in a particular period.
Designated Fees
| Class ID | Amount | Year |
| 1 | 100 | 2013 |
| 1 | 120 | 2014 |
| 2 | 210 | 2014 |
Now, I want to find the total amount each 'Class' is suppose to pay in the current year (thus in 2014), with the summation of what each class was suppose to pay in the previous year ( in this case, the 2013 is the previous Year) and the Previous Year (in this case, the 2014 is the current Year).
Using the below query will give you the amount each Student is suppose to pay from the previous year and current year as far is he/she enrolled in there.
This query gives a good results without any problems
SELECT
a.`Student ID`,
a.`Class ID`,
b.`Amount`,
a.`Year
FROM
`Student Class Table` a
JOIN
`Designated Fees` b
ON
a.`Class ID`=b.`Class ID`
and
a.Year=b.Year
QUERY RESULTS
| Student ID | Class ID | Amount | Year |
| 0001 | 1 | 100 | 2013 |
| 0002 | 1 | 100 | 2013 |
| 0003 | 1 | 120 | 2014 |
| 0001 | 2 | 210 | 2014 |
I want find the total class fees for all the years based on the students enrolled, using the current year as the base year, in this case year 2014 is the current year.
For instance
| Class ID | Total Fees | Year |
| 1 | 120 | 2014 |
| 2 | 410 | 2014 |
The Total Fees for the class with Class ID=1 is 120 because only a student was enrolled in that class within the Year 2013 and 2014 and thier allocated fees for the year 2014 is 120, Also the Total Fees for the
class with Class ID=2 is 410 because two students were enrolled in class with Class ID = 1 in Year 2013 and they were expected to pay an amount of 200, and in the Year 2014 Class 2, only one student enrolled and was expected to pay an amount of 210.
Well, my thoughts on solving this has been complicated, however I added a group by to the query afforementioned, this is wrong that I know. I wanted an Idea as to how to resolve this using either mysql or php, I can't seem to find my way around it.
This will be possible if you have batch numbers for the class from the time, the class was registered. This students in such a class will bear the batch No till they complete the school.
For instance, students in class with Class ID= 1 in Year=2013 will bear the same batch No till they complete. You can choose to create another table and reference it in the Student Class Table depending on how you promote students through the classes over the years.
Student Class Table
| Student ID | Class ID | Year | BatchNo |
| 0001 | 1 | 2013 | 1 |
| 0002 | 1 | 2013 | 1 |
| 0003 | 1 | 2014 | 2 |
| 0001 | 2 | 2014 | 1 |
After Adding the Batch No, you can simply group by the batchNo and sum the amount:
SELECT
a.`Student ID`,
a.`Class ID`,
sum(b.`Amount`),
a.`Year
FROM
`Student Class Table` a
JOIN
`Designated Fees` b
ON
a.`Class ID`=b.`Class ID`
and
a.Year=b.Year
GROUP BY batchNo
This will be your Results
| Class ID | Total Fees | Year |
| 1 | 120 | 2014 |
| 2 | 410 | 2014 |
You can go by this idea and I think, it can work well.

MySQL Count to rows as one

I have a database as laid out below.
mysql> select * from wants where itemname='lamp' order by location;
+------+--------------------+-------------+----------+----------+----------+
| sess | username | room | image | item | priority |
+------+--------------------+-------------+----------+----------+----------+
| 33 | user1#aol.com | Family Room | DSC00649 | Lamp | 1 |
| 235 | user2#yahoo.com | Family Room | DSC00649 | Lamp | 2 |
| 60 | user3#homtmail.com | Foyer | DSC00527 | Lamp | 1 |
| 197 | user4#gmail.com | Foyer | DSC00527 | Lamp | 2 |
| 189 | user4#gmail.com | Living Room | DSC00827 | Lamp | 1 |
| 273 | user5#live.com | Living Room | DSC00827 | Lamp | 2 |
+------+--------------------+-------------+----------+----------+----------+
6 rows in set (0.00 sec)
What I am trying to do is get a count of each item per room.
When I run the query it should look like:
2 Family Room Lamp user1#aol.com user2#yahoo.com
2 Foyer Lamp user3#homtmail.com user4#gmail.com
2 Living Room Lamp user4#gmail.com user5#live.com
Current Query:
$result1 = mysql_query("SELECT username, location, image, itemname, COUNT( itemname ) x FROM wants GROUP BY itemname HAVING x >1 order by location ASC")
This will give the following output:
6 Family Room Lamp luser1#aol.com user2#yahoo.com user3#homtmail.com user4#gmail.com user4#gmail.com user5#live.com
I tried to use Concat to get the count of the first two rows but that did not help,
How can i break these out to get the rooms to read separately, when the Item name is the same?
You need to group by the room instead of the item. Also sounds like you're looking for group_concat to list the users:
select count(*),
room,
group_concat(username)
from wants
where item ='lamp'
group by room
SQL Fiddle Demo

Dividing counts (PHP + MYSQL)

We are trying to sort through people that have purchased items to filter out people that have averaged purchasing over a certain amount of items per year.
Person 1 has bought 1.6 items/year. We want to exclude everyone below a certain amount. How can we do this?
id | item | year
1 | 1 | 2002
1 | 1 | 2003
1 | 3 | 2004
1 | 2 | 2004
2 | 2 | 2004
2 | 2 | 2003
1 | 4 | 2004
We got it. We used the query below and did the math in PHP.
$query = "SELECT id, COUNT(DISTINCT year), COUNT(item) from purchases GROUP BY id"

Categories