I'm trying to look if a record of a table, has at least one record on a pivot table that is used on a many to many relationship.
The table Attendant is:
| ID | NAME |
|----|--------|
| 1 | Name A |
| 2 | Name B |
| 3 | Name C |
And the Attendant_Event pivot table has the following structure
| ID | attendant_id | event_id | uuid |
|----|----------------|------------|--------|
| 1 | 1 | 1 | xxx |
| 2 | 1 | 2 | yyy |
| 3 | 3 | 1 | zzz |
| 4 | 3 | 2 | www |
| 5 | 1 | 3 | xyx |
| 6 | 3 | 3 | rer |
My query is trying to count the attendants that has a least one record on the pivot table, but count all the records as one. For example, the expected result will be a table like this:
| STATUS | COUNT |
|--------|--------|
| YES | 2 |
| NO | 1 |
This results are expected because:
By now, my query is the following:
SELECT IF(uuid <=> NULL, 'NO', 'YES') as status, count(*) as count FROM attendants att LEFT JOIN attendant_event ae ON ae.attendant_id = att.id GROUP BY status
But this is showing me a result like this.
| STATUS | COUNT |
|--------|--------|
| YES | 6 |
| NO | 1 |
This means that, count each of the rows. If we take the previous example, both Attendants with id 1 and 3 has 3 records on the pivot table. So It gives 6 instead of the two that I'm looking for.
What I'm doing wrong?
You may want to select the attendant IDs with their respective YES/NO first, then count them, something like:
SELECT status, count(distinct attendant_id) as count FROM (
SELECT IF(ae.uuid IS NULL, 'NO', 'YES') as status, ae.attendant_id
FROM attendants att LEFT JOIN attendant_event ae ON ae.attendant_id = att.id
GROUP BY ae.attendant_id) x
GROUP BY status
When you make left join, you create intersection, that is larger than attendants table. Your join consists of rows with repeating attendant_id
and different event uuid
.
You can watch the intersection by executing SELECT IF(uuid <=> NULL, 'NO', 'YES') as status, att.id, ae.uuid FROM attendants att LEFT JOIN attendant_event ae ON ae.attendant_id = att.id
. It includes 7 rows, 6 of them are with YES events for two active attendats and 1 row with NO events.
So you should count only distinct values:
SELECT IF(uuid <=> NULL, 'NO', 'YES') as status, count(distinct(att.id)) as count
FROM attendants att
LEFT JOIN attendant_event ae ON ae.attendant_id = att.id
GROUP BY status
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.