Reputation: 359
I want to create a query for project listings that would give the number of registered applications, excluding the ones for which the user does not exist. In this case, considering user 10 does not exist, I should have the query results as folows:
RESULTS
+----+------------+--------------+
| id | project | applications |
+----+------------+--------------+
| 1 | MyProject1 | 3 |
| 2 | MyProject2 | 0 |
| 3 | MyProject3 | 0 |
+----+------------+--------------+
Projects
+----+------------+
| id | name |
+----+------------+
| 1 | MyProject1 |
| 2 | MyProject2 |
| 3 | MyProject3 |
+----+------------+
applications
+----+------+------------+
| id | user | project_id |
+----+------+------------+
| 1 | 3 | 1 |
| 2 | 4 | 1 |
| 3 | 5 | 1 |
| 4 | 10 | 1 |
+----+------+------------+
users
+----+---------+
| id | Name |
+----+---------+
| 1 | Smith |
| 2 | John |
| 3 | Paul |
| 4 | Chris |
| 5 | Gabriel |
+----+---------+
The below query is not excluding the non-existing users:
SELECT `projects` . * , (
SELECT COUNT( * )
FROM `applications`
WHERE `applications`.`project_id` = `projects`.`id`
AND EXISTS (
SELECT `applications`.`id`
FROM `applications` , `users`,`project`
WHERE `application`.`user` = `users`.`id` AND `applications`.`project_id` = `project`.`id`
)
) AS `applications`
FROM `projects` ORDER BY `id` DESC LIMIT 30
Upvotes: 0
Views: 57
Reputation: 962
Based on previous solution
select p.id, p.name, count(u.id)
from projects p left join
applications a
on p.id = a.project_id left join
users u
on a.user = u.id
where u.id is not null
group by p.id, p.name;
When you do a left join, if the search value doesn't exists, it returns null. Then filtering by excluding null users, will give you the result.
Please find a sqlfiddle to illustrate it : http://www.sqlfiddle.com/#!9/cbfec6/3
But easiest solution would be
select p.id, p.name, count(u.id)
from projects p,applications a, users u
where a.user = u.id
and p.id = a.project_id
group by p.id, p.name;
Upvotes: 0
Reputation: 94894
Your query looks overly complicated. This should do:
select
id,
name as project,
(
select count(*)
from applications a
where a.project_id = p.id
and a.user in (select id from users)
) as applications
from projects p;
Upvotes: 0
Reputation: 1269693
I think you want left join
and group by
:
select p.id, p.name, count(u.id)
from projects p left join
applications a
on p.id = a.project_id left join
users u
on a.user_id = u.id
group by p.id, p.name;
However, you might want to think about fixing the data. It seems like there should be foreign key relationships between applications and projects and applications and users. The ability to have an invalid user means that there is no valid foreign key relationship to users.
Upvotes: 1