Reputation: 87
i have a problem in MySQL where I use the COUNT function for conditions. However, when combining this with joins, although I use grouping, the COUNT values include ALL rows, even the ones filtered out. I'm providing a minimal working example, which however maybe does not make a practical sense or is designed smartly. So assume I have 3 tables:
So basically I have products and teams with ids and names. Products can be active (lets say that means that they are still in production or so). And then I have a relation which team is working on which product. To explain my problem, assume the following minimal amount of data to clarify the problem is contained inside the tables:
Now the query that I want to do is, in plain english: "I want all teams that are working on exactly 2 products while atleast one product must be active." The query in general works and is the following in mysql:
SELECT
teams.*,
"r_count:",
r_count.*,
COUNT(r_count.productId),
"r_active:",
r_active.*,
"p_active:",
p_active.*
FROM teams
INNER JOIN rel_production r_active ON r_active.teamId = teams.teamId
INNER JOIN products p_active ON p_active.productId = r_active.productId AND p_active.active
INNER JOIN rel_production r_count ON r_count.teamId = teams.teamId
GROUP BY teams.teamId, r_active.teamId
HAVING COUNT(r_count.productId) = 2 #4 is the problem!!!!!!!!!!!!!
Now them problem is with team 1. Because it is working on 2 active products, COUNT(r_count.productId) will be 4 and not 2. So my query will filter it out.
Here is the screenshot with the result without the HAVING clause:
I see why this happens, because the two inner joins on rel_production will cause 4 rows to be generated. But then they are merged always together to one using the GROUP BY. So what I need is the COUNT after the GROUP and not before.
How can I fix this?
Upvotes: 0
Views: 39
Reputation: 522501
Perform the filtering on teams in a separate subquery, and then join to that:
SELECT
t1.teamId,
t1.name
FROM teams t1
INNER JOIN
(
SELECT t1.teamId
FROM rel_production t1
INNER JOIN products t2
ON t1.productId = t2.productId
GROUP BY t1.teamId
HAVING COUNT(DISTINCT t1.productId) = 2 AND SUM(t2.active) > 0
) t2
ON t1.teamId = t2.teamId;
Upvotes: 2