Reputation: 1805
I have a DB schema something like this:
CREATE TABLE projects (project_id int);
CREATE TABLE project_members (user_id int, project_id int);
CREATE TABLE project_issues (issue_id int, project_id int);
What I want is to find all projects which have 10 or more members as well as 10 or more issues. I am struggling to come up with a query for this.
I want output something similar to:
project_id | members | issues
-----------+---------+-------
65 | 100 | 23
93 | 78 | 45
Preferably sorted by members then issues.
I have come up with:
SELECT projects.project_id, COUNT(project_members.user_id) FROM
project_members LEFT JOIN projects ON
project_members.project_id = projects.project_id GROUP BY projects
ORDER BY count;
but do not know how to take it to the next level in counting the issues as well.
I am using PostgreSQL 9.1
Upvotes: 0
Views: 1004
Reputation: 657617
A bit simpler & faster:
SELECT p.project_id, m.members, i.issues
FROM projects p
JOIN (
SELECT project_id, count(*) AS members
FROM project_members
GROUP BY project_id
HAVING count(*) >= 10
) m USING (project_id)
JOIN (
SELECT project_id, COUNT(*) AS issues
FROM project_issues
GROUP BY project_id
HAVING count(*) >= 10
) i USING (project_id)
ORDER BY m.members DESC, i.issues DESC;
Since you want projects,
which have 10 or more members as well as 10 or more issues
.. you can eliminate non-qualifying candidates early with JOIN
and HAVING
for a faster result.
Plus some other minor tweaks.
And make that >= 10
or > 9
for "10 or more"!
Be wary of "proxy cross joins":
Two SQL LEFT JOINS produce incorrect result
Upvotes: 4
Reputation: 4412
This could probably be done more efficient, but it gives the correct results.
SELECT
p.project_id,
m.members,
i.issues
FROM projects AS p
LEFT JOIN
(
SELECT project_id, COUNT(user_id) AS members
FROM project_members
GROUP BY project_id
) AS m
ON p.project_id = m.project_id
LEFT JOIN
(
SELECT project_id, COUNT(issue_id) AS issues
FROM project_issues
GROUP BY project_id
) AS i
ON p.project_id = i.project_id
WHERE members > 10 AND issues > 10
ORDER BY members, issues;
Upvotes: 2