Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Multiple COUNT() from two tables, within a LEFT JOIN

Tags:

sql

join

count

i have three tables, i want to select all data from one of the tables, and also collect a COUNT of how many times that specific row of data is linked in the other two tables.

So, SELECT all data from site_projects. Then return a COUNT of site_project_members WHERE site_projects.id = site_project_members.pid and also return a COUNT of site_project_tasks WHERE site_projects.id = site_project_members.pid

I hope i'm making sense, to the query, it looks correct. and it querys the database (MySQL) with no problems. Except it returns a sum of both of the counts as both things. (see below the table structures)

site_projects

id | title     | desc      | start      | deadline   | progress

1  | Project 1 | a project | 1321748906 | 1329847200 | 20

site_project_members

id | pid | uid | img | hidden
1  | 1   | 1   | 1   | 0
2  | 1   | 2   | 2   | 0

site_project_tasks

id | pid | desc   | completed
1  | 1   | Task 1 | 1
1  | 1   | Task 2 | 0

Here is my query:

SELECT p.`id`, p.`title`, p.`desc`, p.`progress`, p.`start`, p.`deadline`, COUNT(m.`id`) as `members`, COUNT(t.`id`) as `tasks` FROM `site_projects` p LEFT JOIN `site_project_members` m ON p.`id`=m.`pid` LEFT OUTER JOIN `site_project_tasks` t ON p.`id`=t.`pid` ORDER BY p.`id` ASC

The result i get is:

id | title     | desc      | progress | start      | deadline   | members | tasks
1  | Project 1 | a project | 20       | 1321748906 | 1329847200 | 4       | 4

Both of the "4" values should be 2. however they are not :S Anyone able to help? Much Appreciated

Thanks, Dan

like image 503
Dan Spiteri Avatar asked Jan 31 '12 18:01

Dan Spiteri


People also ask

How join multiple tables with left join in SQL?

SELECT column names FROM table1 LEFT JOIN table2 ON table1. matching_column = table2. matching_column; Note: For example, if you have a left table with 10 rows, you are guaranteed to have at least 10 rows after applying join operation on two tables.

How do I count records from two tables in SQL?

To achieve this for multiple tables, use the UNION ALL. select sum(variableName. aliasName) from ( select count(*) as yourAliasName from yourTableName1 UNION ALL select count(*) as yourAliasName from yourTableName2 ) yourVariableName; Let us implement the above syntax.

Can LEFT join increase row count?

Left Outer Join returns all of the rows in the current data and all the data from the matching rows in the joined data, adding rows when there is more than one match. This can result in an expanded row count.

How do I join two tables with multiple conditions in SQL?

Multi-Table JOIN syntax. FROM table-name1. JOIN table-name2 ON column-name1 = column-name2. JOIN table-name3 ON column-name3 = column-name4.


2 Answers

SELECT p.id , p.title , p.desc , p.progress , p.start , p.deadline , 
   COALESCE( m.cnt, 0 ) AS members,
   COALESCE( t.cnt, 0 ) AS tasks
FROM site_projects p
LEFT JOIN 
  ( SELECT pid, COUNT(*) AS cnt FROM
    site_project_members
    GROUP BY pid ) m
ON p.id = m.pid
LEFT JOIN
  ( SELECT pid, COUNT(*) AS cnt FROM
    site_project_tasks
    GROUP BY pid ) t
ON p.id = t.pid
ORDER BY p.id ASC
like image 92
piotrm Avatar answered Oct 14 '22 22:10

piotrm


SELECT p.`id`, p.`title`, p.`desc`, p.`progress`, p.`start`, p.`deadline`,
     (SELECT COUNT(*) FROM site_project_members m WHERE p.`id`=m.`pid`) AS `members`,
     (SELECT COUNT(*) FROM site_project_tasks t WHERE p.`id`=t.`pid`) AS `tasks`
FROM `site_projects` p
ORDER BY p.`id` ASC

That should really do the trick.

like image 44
dgw Avatar answered Oct 14 '22 23:10

dgw