#mysql
#mysql
Вопрос:
Я пытаюсь посмотреть, имеет ли запись таблицы хотя бы одну запись в сводной таблице, которая используется в отношениях «многие ко многим».
Обслуживающий персонал таблицы:
| ID | NAME |
|----|--------|
| 1 | Name A |
| 2 | Name B |
| 3 | Name C |
И сводная таблица Attendant_Event имеет следующую структуру
| 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 |
Мой запрос пытается подсчитать обслуживающий персонал, у которого есть хотя бы одна запись в сводной таблице, но считать все записи как одну.
Например, ожидаемым результатом будет таблица, подобная этой:
| STATUS | COUNT |
|--------|--------|
| YES | 2 |
| NO | 1 |
Эти результаты ожидаемы, потому что:
- Только участники с идентификаторами 1 и 3 имеют запись в таблице Attendant_Event. Это говорит нам о том, что количество обслуживающих лиц со строками в сводной таблице равно 2.
- У обслуживающего персонала с идентификатором 2 нет записей, поэтому число обслуживающих сотрудников, у которых нет записей в сводной таблице, равно 1.
На данный момент мой запрос следующий:
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
Но это показывает мне такой результат.
| STATUS | COUNT |
|--------|--------|
| YES | 6 |
| NO | 1 |
Это означает, что подсчитайте каждую из строк. Если мы возьмем предыдущий пример, оба участника с идентификаторами 1 и 3 имеют по 3 записи в сводной таблице. Таким образом, он дает 6 вместо двух, которые я ищу.
Что я делаю не так?
Ответ №1:
Возможно, вы захотите сначала выбрать идентификаторы сопровождающих с их соответствующими ДА / НЕТ, а затем посчитать их, что-то вроде:
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
Комментарии:
1. Спасибо, это сработало, но я должен перевести запрос в конструктор запросов Laravel. Это было то, что я думал сделать, но я не знал как. Спасибо
Ответ №2:
Когда вы выполняете левое соединение, вы создаете пересечение, которое больше, чем таблица участников. Ваше соединение состоит из строк с повторяющимися attendant_id
и разными событиями uuid
.
Вы можете наблюдать за пересечением , выполнив 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
команду . Он включает в себя 7 строк, 6 из них с событиями «ДА» для двух активных участников и 1 строка без событий.
Таким образом, вы должны считать только отдельные значения:
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