How to SUM two column in My SQL left join - mysql

So i have table Project
---------------------------------
project_id | name|
---------------------------------
1 | project 1 |
2 | project 2 |
---------------------------------
table 02 report
----------------------------------------------------
report_id | report_emp | report_hours |report_project_id|
---------------------------------------------------
1 | 1 | 5 | 1 |
2 | 2 | 7 | 1 |
3 | 1 | 9 | 2 |
4 | 2 | 6 | 1 |
5 | 3 | 8 | 2 |
--------------------------------------------------
and table 03 emp
----------------------------------------------
emp_id | emp_hourly_cost | name |
-----------------------------------------------
1 | 8.5 | A |
2 | 10 | B |
3 | 12 | C |
4 | 9 | D |
5 | 7.5 | D |
-----------------------------------------------
as a final result i wanted to get this table
---------------------------------------------
project | hours | total cost |
---------------------------------------------
1 | 18 | 172.5 |
2 | 17 | 172.5 |
---------------------------------------------
until now i only got the project with total hours but not total cost in this statement
SELECT * from projects left join(select sum(report_hours ) as hours , daily_reports_project_id
from project_id group by report_id)x on x.report_project_id= projects.project_id;
total cost would be sum of all > [total hours of the project of the emp in table 2 * emp_hourly_cost in table 3 ]
i appreciation the help.

Join the tables and aggregate:
SELECT p.project_id project,
SUM(r.report_hours) hours,
SUM(r.report_hours * e.emp_hourly_cost) total_cost
FROM project p
LEFT JOIN report r ON r.report_project_id = p.project_id
LEFT JOIN emp e ON e.emp_id = r.report_emp
GROUP BY project_id;
If there are projects without reports and you want to get 0 instead of NULL as result use also COALESCE():
SELECT p.project_id project,
COALESCE(SUM(r.report_hours), 0) hours,
COALESCE(SUM(r.report_hours * e.emp_hourly_cost), 0) total_cost
FROM project p
LEFT JOIN report r ON r.report_project_id = p.project_id
LEFT JOIN emp e ON e.emp_id = r.report_emp
GROUP BY project_id;
See the demo.

Try this
SELECT sum(column_name1 + column_name2) as 'Total'
This line is selecting the sum of column_name1 and column_name2 from table1, and giving it an alias of 'Total'
FROM table1
This line is specifying that we want data from table1
LEFT JOIN table2
This line is joining table1 with table2 using a LEFT JOIN. This means that all data from table1 will be included, even if there is no matching data in table2
ON table1.column_name1 = table2.column_name2;
This line is specifying the conditions for the join. In this case, it is saying that column_name1 from table1 should match column_name2 from table2
SELECT sum(column_name1 + column_name2) as 'Total'
FROM table1
LEFT JOIN table2
ON table1.column_name1 = table2.column_name2;

Related

How can I not take in consideration values join without record on the db

I'm in front of a "minor" problem taht looks easy but I didn't suceed to resolve it.
I have three tables in my Database :
Table gp
____________
id | name |
____________
1 | Le Mans|
2 | Toulon |
3 | Rennes |
Table player
____________
id | name |
____________
1 | Thibaut|
2 | Fred |
3 | Samir |
Table Records
_____________________________
id | gp_id | player_id | time
_____________________________
1 | 1 | 1 | 17860
2 | 2 | 1 | 11311
3 | 3 | 1 | 33133
4 | 3 | 2 | 11113
5 | 2 | 2 | 44444
6 | 1 | 2 | 13131
7 | 1 | 3 | 11111
8 | 3 | 3 | 21112
I want to get a sum of time for players that have a record on every gp ( so in my case, just players Thibaut and Fred have a record on the 3 gp ( Samir has just a record on two gp ) ).
I have no idea how I can get that, of course this SQL query is retrieving a sum but from this query I want to escape the guys that don't have a record on every GPs, but I'm blocked at that point ...
SELECT p.name, sum(time)
from records r
join gp g on r.gp_id = g.id
join player p on r.player_id = p.id
group by r.player_id
Thanks in advance guys !
You could use having count to exclude the records that don't have a record on every GPs.
Try:
select p.name,
sum(`time`) as tot_sum
from records r
inner join player p on r.player_id=p.id
inner join gp g on g.id=r.gp_id
group by p.name
having count(distinct gp_id) = (select count(distinct id) from gp)
https://dbfiddle.uk/t8QwSFDY
having count(distinct gp_id) = (select count(distinct id) from gp) will match only the records in the record table that have a record on every gp.

Join Table B to Table A only if entry in Table B equals entry in Table C

I have 3 tables. clients, sales and potential_sales.
The basic structure is as follows:
Clients Table:
+-----------+-------+----------------+
| client_id | name | address |
+-----------+-------+----------------+
| 1 | john | 12 blue ave |
| 2 | paul | 34 green lane |
| 3 | peter | 69 yellow road |
+-----------+-------+----------------+
Potential Sales Table:
+----------+------------+---------------------+
|product_id | client_id | received_free_promo |
+-----------+------------+---------------------+
| 3 | 1 | 1 |
| 4 | 2 | 0 |
| 5 | 2 | 1 |
+-----------+------------+---------------------+
Sales:
+----------+-----------+-----------+
| sales_id | client_id | product_id |
+----------+-----------+------------+
| 1 | 2 | 4 |
| 2 | 43 | 4 |
| 3 | 2 | 5 |
| 4 | 18 | 93 |
+----------+-----------+------------+
I want to join clients and potential_sales tables ONLY IF
1) received_promo equals 1 AND
2) they actually bought the promo package (i.e. the product_id for the potential sale has an entry into the sales table ). If they didn't eventually buy the free_promo product then I do not want to join the clients and potential_sales table at all. This is important - I can't simply JOIN to figure it out because this is only a small part of a bigger query and I can't afford to JOIN for no reason.
(Here is how I would like it to work. It's mainly pseudo-code to describe what I want to happen)
SELECT
c.*
FROM
clients c
LEFT JOIN potential_sales ps ON ps.client_id=c.id
LEFT JOIN sales ps ON s.product_id=ps.product_id
IF(s.sales_id) JOIN potential_sales ps ON ps.client_id=c.id
How do I do this in MySQL? I haven't come close to a solution. Please help!
Try this:
SELECT A.*, B.product_id, B.received_free_promo
FROM Clients A JOIN
(SELECT * FROM PotentialSales
WHERE received_free_promo=1) B
ON A.client_id=B.client_id
WHERE EXISTS (SELECT 1 FROM Sales C
WHERE A.client_id=C.client_id
AND B.product_id=C.product_id);
See Demo on SQL Fiddle.
What you are missing is the EXISTS clause:
SELECT
C.*,
P.*
FROM
Clients AS C
INNER JOIN PotentialSales AS P ON C.client_id = P.client_id
WHERE
P.received_free_promo = 1 AND
EXISTS (
SELECT
'the client already sold that product'
FROM
Sales AS S
WHERE
S.client_id = C.client_id AND
S.product_id = P.product_id)
Try this..." select * from client as c natural join potential as p join sales as s on p.product_id = s.product_id where received_promo = 1". select * will mention everything from all the 3 tables. You can choose what you want as the result.

How to SUM column in MySQL left join

So i have table cont_selling
---------------------------------
cont_selling_id | date |
---------------------------------
1 | 2015-05-24 |
2 | 2015-06-06 |
---------------------------------
table 02 cont_sold
----------------------------------------------------
cont_sold_id | cont_selling_id | price |
---------------------------------------------------
1 | 1 | 10 |
2 | 1 | 10 |
3 | 1 | 30 |
4 | 2 | 20 |
5 | 2 | 10 |
--------------------------------------------------
and table 03 payment
----------------------------------------------
payment_id | cont_selling_id | paid |
-----------------------------------------------
1 | 1 | 10 |
2 | 2 | 10 |
3 | 1 | 20 |
4 | 1 | 10 |
5 | 2 | 10 |
-----------------------------------------------
now i need to SELECT table based on
now i want to merge all these three tables based on cont_selling table cont_selling_id column
and want to SUM cont_sold table price column and payment table paid column
this is what i want to do
expecting output
---------------------------------------------
cont_selling_id | price | paid |
---------------------------------------------
1 | 50 | 40 |
2 | 30 | 20 |
---------------------------------------------
so i tried like this in mysql query but it give wrong sum result
SELECT
SUM(Z.price) as total,
SUM(P.amount) as paid
FROM cont_selling S
LEFT JOIN cont_sold Z
ON S.cont_selling_id = Z.cont_selling_id
LEFT JOIN payment P
ON S.cont_selling_id = P.cont_selling_id
GROUP BY S.cont_selling_id
for this above query i m getting output like this
---------------------------------------------
cont_selling_id | price | paid |
---------------------------------------------
1 | 150 | 40 |
2 | 60 | 120 |
---------------------------------------------
Here how you can do it using the aggegare part into inner queries and then join
select
cs.cont_selling_id,
price,
paid
from cont_selling cs
left join(
select sum(price) as price , cont_selling_id from cont_sold
group by cont_selling_id
)x on x.cont_selling_id = cs.cont_selling_id,
left join(
select sum(paid) as paid , cont_selling_id from payment
group by cont_selling_id
)y
on y.cont_selling_id = cs.cont_selling_id;
You should make two different queries with SUM and then combine them to get the desired result:
SELECT T1.cont_selling_id,T1.price,T2.paid
FROM
(SELECT c.cont_selling_id,SUM(cs.price) as price
FROM cont_selling c LEFT JOIN
cont_sold cs ON c.cont_selling_id=cs.cont_selling_id
GROUP BY c.cont_selling_id) as T1 JOIN
(SELECT c.cont_selling_id,SUM(p.paid) as paid
FROM cont_selling c LEFT JOIN
payment p ON p.cont_selling_id=c.cont_selling_id
GROUP BY c.cont_selling_id) as T2 ON T1.cont_selling_id=T2.cont_selling_id
Result:
cont_selling_id price paid
----------------------------
1 50 40
2 30 20
Sample result in SQL Fiddle.
This untested query should work:
with a as(select cont_selling_id , sum(price) as totalprice from cont_sold group by cont_selling_id),
with a as(select cont_selling_id , sum(paid) as totalpaid from payment group by cont_selling_id),
select c.cont_selling_id , totalprice, totalpaid from cont_selling c left join a.count_selling_id = c.count_selling_id
left join b.count_selling_id = c.count_selling_id
You have to create temporary tables, because there is no dependency between your table for price and paid.

Join on same column name

Hello there I want to get data from two tables that share same column name. My table structure are
Table patients
---------------------------------------
| id | affiliate_id | somecolumn |
---------------------------------------
| 1 | 8 | abc |
---------------------------------------
| 2 | 8 | abc |
---------------------------------------
| 3 | 9 | abc |
---------------------------------------
Table Leads
---------------------------------------
| id | affiliate_id | someothern |
---------------------------------------
| 1 | 8 | xyz |
---------------------------------------
| 2 | 8 | xyz |
---------------------------------------
| 3 | 3 | xyz |
---------------------------------------
Now my requirement was to get COUNT(ID) from both tables in a single query. I want result like
----------------------------------------------------
| affiliate_id | total_patients | total_leads |
----------------------------------------------------
| 8 | 2 | 2 |
----------------------------------------------------
| 9 | 1 | 0 |
----------------------------------------------------
| 3 | 0 | 1 |
----------------------------------------------------
I wrote following query
SELECT `p`.`affiliate_id`, COUNT(p.id) AS `total_patients`,
COUNT(cpl.id) AS `total_leads`
FROM `patients` AS `p`
INNER JOIN `leads` AS `cpl` ON p.affiliate_id =cpl.affiliate_id
GROUP BY `p`.`affiliate_id`
But I am not getting result . This query results giving only one affiliate with same number of total_patients and total_leads
The problem is that you need to get a list of the distinct affiliate_id first and then join to your other tables to get the result:
select a.affiliate_id,
count(distinct p.id) total_patients,
count(distinct l.id) total_leads
from
(
select affiliate_id
from patients
union
select affiliate_id
from leads
) a
left join patients p
on a.affiliate_id = p.affiliate_id
left join leads l
on a.affiliate_id = l.affiliate_id
group by a.affiliate_id;
See SQL Fiddle with Demo
Two ways:
Select l.affiliate_id ,
count(distinct p.id) patientCount,
count(distinct l.id) LeadCOunt
From patients p Join leads l
On l.affiliate_id = p.Affiliate_id
Group By l.affiliate_id
or, (assuming affiliates are in their own table somewhere)
Select Affiliate_id,
(Select Count(*) From Patients
Where Affiliate_id = a.Affiliate_id) patientCount,
(Select Count(*) From Leads
Where Affiliate_id = a.Affiliate_id) LeadCount
From affiliates a

Concatenating rows in relation to a JOIN

Suppose I have a cooking show:
cookingepisodes
id | date
---------------
1 | A
2 | B
3 | C
4 | D
…
This show reviews products in these categories (left) and are linked by the table to the right:
tests testitems
id | name id | episodeid | testid | name
------------ ------------------------------------
1 | cutlery 1 | 1 | 1 | Forks
2 | spices 2 | 2 | 1 | Knives
3 | 4 | 1 | Spoons
4 | 4 | 2 | Oregano
My desired output is this:
showid | testid | testname
4 | 1,2 | cutlery, spices
3 | NULL | NULL
2 | 1 | cutlery
1 | 1 | cutlery
I've tried using this query, and it works as long as I don't need to concatenate the results (when there are two tests on the same episode). Then the join will create multiple rows based on the number of
SELECT DISTINCT e.*, i.testid, t.name AS testname
FROM cookingepisodes AS e
LEFT OUTER JOIN testitems AS i ON i.episodeid = e.id
LEFT OUTER JOIN tests AS t ON i.testid = t.id
ORDER BY e.date DESC
I've also tried something like this, but I can't get it to work because of the outer block reference (e.id):
JOIN (
SELECT GROUP_CONCAT(DISTINCT testid)
FROM testitems
WHERE testitems.episodeid = e.id
) AS i
Any tips on how I can solve this without restructuring the database?
Try this one -
SELECT
ce.id showid,
GROUP_CONCAT(te.testid) testid,
GROUP_CONCAT(t.name) testname
FROM cookingepisodes ce
LEFT JOIN testitems te
ON te.episodeid = ce.id
LEFT JOIN tests t
ON t.id = te.testid
GROUP BY
ce.id DESC;