MYSQL/PHP sum with group by - php

tableA
id B_id C_id
1 1 0
2 1 0
3 0 1
4 0 2
5 0 2
6 0 2
tableB
id amount quantity
1 10 2
tableC
id amount quantity
1 6 1
2 15 3
I have this kind of database and I know it is not structured very well because I only continued this website and I wasn't given much time to restructure the website.
My question is how can i get the total amount of tableB and tableC using a LEFT JOIN of the two tables to tableA. As you can see the quantity in tableB and tableC will make the same number of tableA record. I was able to get each of the transactions amount using this code:
SELECT *
FROM tableA A
LEFT JOIN tableB B ON A.id = B.id
LEFT JOIN tableC C ON C.id = A.id
GROUP BY B.id, C.id
It would return:
id B_id C_id B.id B.amount B. quantity C.id C.amount C.quantity
1 1 0 1 10 2 0 0 0
3 0 1 0 0 0 1 6 1
4 0 2 0 0 0 2 15 3
but now I want to get the total using mysql SUM but GROUP BY cannot be used with the aggregate function SUM so the total should be: 10+6+15 = 31

Is this what you want?
SELECT coalesce(sum(b.quantity), 0) + coalesce(sum(c.quantity), 0)
FROM tableA A LEFT JOIN
tableB B
ON A.id = B.id LEFT JOIN
tableC C
ON C.id = A.id;
This returns the total across the two tables.
EDIT:
If you just want the sum of tables b and c, what is table a for? Is this what you want?
select amountb + amountc
from (select sum(amount) as amountb from tableb) b cross join
(select sum(amount) as amountc from tablec) c;

Related

How to show only those sellers who have created at-least one product

I have one sellers table where sellerid column is sno and I have products table where sellerid is sellerid , I want to get those sellers who are not blocked (there is column named flag in sellers table) and have created at least one product so I write this(or maybe copy this)
SELECT e.*, count(*) AS count
FROM sellers AS e
left join products AS r ON e.sno = r.sellerid
where NOT e.flag='1'
GROUP BY e.sno
Now I do my logic through:
if($row["count"] == 1){
continue;
}
It is producing incorrect result
-- fake table data
CREATE TABLE sellers SELECT 1 sno, 0 flag UNION SELECT 2, 0 UNION SELECT 3, 0;
CREATE TABLE products SELECT 1 sellerid UNION ALL SELECT 1 UNION ALL SELECT 2;
SET sql_mode := '';
-- initial query
SELECT e.*, count(*) AS `count`
FROM sellers AS e
left join products AS r ON e.sno = r.sellerid
where NOT e.flag='1'
GROUP BY e.sno
sno
flag
count
1
0
2
2
0
1
3
0
1
-- counting joined values, not rows (NULLs are ignored)
SELECT e.*, count(r.sellerid) AS `count`
FROM sellers AS e
left join products AS r ON e.sno = r.sellerid
where NOT e.flag='1'
GROUP BY e.sno
-- further filtering by count>0 needed
sno
flag
count
1
0
2
2
0
1
3
0
0
-- join only rows which have matched rows in second table
SELECT e.*, count(*) AS `count`
FROM sellers AS e
inner join products AS r ON e.sno = r.sellerid
where NOT e.flag='1'
GROUP BY e.sno
-- no further filtering needed
sno
flag
count
1
0
2
2
0
1
db<>fiddle here

multiple count and sum MySQL function returning wrong values with multiple joins in MySQL result

Table mpkids_students AS A
id BranchId Email Mobile StudentId
9497 25 mpsuraj2016#gmail.com 8700698773 25
9498 25 m016#gmail.com 8700698776 26
Table mpkids_student_image_gallery AS B
id like_count student_id
1 25 27
Table mpkids_visitors AS C
id student_id
1 9497
2 9497
3 9497
Table mpkids_visitors_count AS D
id visitor_count student_id
1 4 23
Table mpkids_image_likes AS E
id student_id
1 67
Table mpkids_relatives_data AS F
id student_id rel_email rel_mobile
1 9497 kushwahji#gmail.com 9009859691
2 9497 kushwah#gmail.com 7566403326
3 9497 kushwah#gmail.com 1236403326
4 9497 suraj#gmail.com 123640332
Table mpkids_paidstatus AS G
id student_id Received
1 9497 7500
2 9497 3000
3 9497 3000
MYSQL QUERY
SELECT A.id as student_id,
COUNT(DISTINCT B.id) as images,
COUNT(DISTINCT C.id)+ COUNT(DISTINCT D.visitor_count) as visits,
count(DISTINCT E.id) + SUM(B.like_count) as likes,
COUNT(DISTINCT A.Email)+COUNT(DISTINCT F.rel_email) as emails,
COUNT(DISTINCT A.Mobile)+COUNT(DISTINCT F.rel_mobile) as moibles,
SUM(G.Received) as Received
FROM mpkids_students AS A
LEFT JOIN mpkids_student_image_gallery AS B ON B.student_id = A.id
LEFT JOIN mpkids_visitors AS C ON C.student_id = A.id
LEFT JOIN mpkids_visitors_count AS D ON D.student_id = A.id
LEFT JOIN mpkids_image_likes AS E ON E.student_id = A.id
LEFT JOIN mpkids_relatives_data AS F ON F.student_id = A.id
LEFT JOIN mpkids_paidstatus AS G ON G.student_id = A.id
WHERE A.BranchId = 25
GROUP BY A.id
ORDER BY A.StudentId DESC
Result:
student_id images visits likes emails moibles Received
9497 0 3 NULL 4 5 202500
9498 0 0 NULL 1 1 NULL
Problem Explanation:
Received Field returning wrong value i have tried many queries but not getting solution
Received Field correct value 13500 for student_id = 9497
Please help me to find solution.
You are getting wrong output because, when you are joining based on studentid, you are getting multiple records from mpkids_paidstatus table for each student, which is adding up and returning a wrong output.
You can also write your query like following using subquery.
SELECT A.id as student_id,
COUNT(DISTINCT B.id) as images,
COUNT(DISTINCT C.id)+ COUNT(DISTINCT D.visitor_count) as visits,
count(DISTINCT E.id) + SUM(B.like_count) as likes,
COUNT(DISTINCT A.Email)+COUNT(DISTINCT F.rel_email) as emails,
COUNT(DISTINCT A.Mobile)+COUNT(DISTINCT F.rel_mobile) as moibles,
(select SUM(Received) from mpkids_paidstatus ps where ps.student_id=a.id) as Received
FROM mpkids_students AS A
LEFT JOIN mpkids_student_image_gallery AS B ON B.student_id = A.id
LEFT JOIN mpkids_visitors AS C ON C.student_id = A.id
LEFT JOIN mpkids_visitors_count AS D ON D.student_id = A.id
LEFT JOIN mpkids_image_likes AS E ON E.student_id = A.id
LEFT JOIN mpkids_relatives_data AS F ON F.student_id = A.id
WHERE A.BranchId = 25
GROUP BY A.id
ORDER BY A.StudentId DESC

Php, MySql join 3 tables ,and calculate SUM

I have 3 tables project, times and expense. I want to join all 3 of them and calculate sum as well as retrieve all the matching records.
Here are my tables:
projects:
id name
=====================
1 First Project
2 Second Project
times:
id project_id hours billed
===================================================
1 1 2.0 1
2 1 3.0 0
3 2 4.30 0
expense:
id project_id amount billed
==================================================
1 1 120.00 0
2 2 35.00 1
3 2 55.00 0
4 2 45.00 0
and here is my query:
SELECT
SUM(t.hours) as total_hours,
SUM(e.amount) as total_amount,
p.name
FROM
`projects` AS p
LEFT JOIN `expense` AS e
ON e.project_id = p.id
LEFT JOIN `times` AS t
ON t.project_id = p.id
WHERE t.billed = 0
AND e.billed = 0
GROUP BY p.id;
But for some reason I cant make it to work, I end up with no records.
The result should look something like:
Name Total Hours Total Expense
==============================================
First Project 3.00 120.00
----------------------------------------------
Second Project 7.30 100.00
----------------------------------------------
You just have the table aliases the wrong way around:
SELECT
SUM(e.hours) as total_hours,
SUM(t.amount) as total_amount,
p.name
FROM
`projects` AS p
LEFT JOIN `expense` e
ON e.project_id = p.id
LEFT JOIN `times` t
ON t.project_id = p.id
WHERE t.billed = 0
AND e.billed = 0
GROUP BY p.id;
Works as expected: http://sqlfiddle.com/#!9/48bfd1/3

How to update single rows in duplicate entries

I have two tables t1 and t2
t1->
id line Amt
----------- ----------- -----------
1 1 0
1 2 0
2 1 0
2 2 0
2 3 0
3 3 0
3 4 0
3 5 0
4 2 0
4 3 0
--------------------------
t2->
id amt
----------- -----------
1 500
2 350
3 750
4 400
In this case I need to update t1 with amount from t2. But I need to update only one row for each id on minimum line. I can do it in MSSQL using the following query-
update a set a.amt=c.amt from T1 a inner join (
select id,min(line) line from T1 group by Id) b
on a.id=b.id and a.line=b.line
Inner join T2 c on a.id=c.Id
I want to do it in MYSQL. Is there any idea to do something like this
You need to tweak your syntax remove from clause, move set clause after joins part
update T1 a
inner join (
select id,min(line) line from T1 group by Id
) b on a.id=b.id and a.line=b.line
inner join T2 c on a.id=c.Id
set a.amt=c.amt
DEMO

MySQL display team standings from results table

I have two tables:
teams
---------------------
team_id team_name
---------------------
1 Lakers
2 Clippers
3 Grizzlies
4 Heat
results
...............................................................
game_id team_id1 team_id2 team1_score team2_score
1 1 2 20 30
2 1 3 40 50
3 2 1 50 60
4 4 2 20 30
5 1 2 20 30
My question is, how can I then create standings results for this tables based on results sorted by points, like this:
...............................................................
Position team_name total_points games_played
1 Lakers 140 4
2 Clippers 110 3
3 Grizzlies 50 1
4 Heat 20 1
I guess what you would like to do is something like this:
EDITED
SET #num :=0;
SELECT (#num := #num + 1) as Position,team_name,total_points,games_played
FROM (
SELECT teams.team_name, SUM(p) as total_points, count(*) as games_played
FROM (
SELECT team_id1 as id, team1_score as p FROM results
UNION ALL
SELECT team_id2 as id, team2_score as p FROM results
) t
INNER JOIN teams ON t.id = teams.team_id
GROUP BY id,teams.team_name ) t2
ORDER BY total_points DESC;
SQLFiddle is here : http://www.sqlfiddle.com/#!2/5bf2c/1
If you would like to display all teams, even if some teams did not play a single game, you could go like this:
SET #num :=0;
SELECT (#num := #num + 1) as Position,team_name,total_points,games_played
FROM (
SELECT
teams.team_name,
SUM(p) as total_points,
SUM(f) as games_played
FROM (
SELECT team_id1 as id, team1_score as p, 1 as f FROM results
UNION ALL
SELECT team_id2 as id, team2_score as p, 1 as f FROM results
UNION ALL
SELECT team_id as id, 0 as p, 0 as f FROM teams
) t
INNER JOIN teams ON t.id = teams.team_id
GROUP BY id,teams.team_name ) t2
ORDER BY total_points DESC;
SQLFiddle is here: http://www.sqlfiddle.com/#!2/8ecf5d/9
Hope this helps.
I may have renamed a couple of your columns... oh, and teams 1 and 2 are tied so you need to say a little more about how to resolve that...
SELECT t.*
, COUNT(*) p
, SUM(score) pts
FROM
(
SELECT home_team_id team_id,home_team_score score FROM results
UNION ALL
SELECT away_team_id,away_team_score FROM results
) x
JOIN teams t
ON t.team_id = x.team_id
GROUP
BY t.team_id
ORDER
BY pts DESC;
select team_id,team_name,sum(sc1) ,sum(ct1) from
(select team_id,teams.team_name,sc1,ct1 from
(select team_id1,sum(team1_score)as sc1,count(team_id1) as ct1 from results group by team_id1) as srtbl1,teams
where srtbl1.team_id1 =teams.team_id
union
select team_id,teams.team_name,sc2,ct2 from
(select team_id2,sum(team2_score)as sc2 ,count(team_id2) as ct2 from results group by team_id2) as srtbl2,teams
where srtbl2.team_id2 =teams.team_id) sctbl
group by team_id;
and I think you make a mistake in calculating .

Categories