Я пытаюсь проверить, есть ли в записи таблицы хотя бы одна запись в сводной таблице, которая используется в отношениях «многие ко многим».

Обслуживающий персонал таблицы:

| 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. Только операторы с идентификаторами 1 и 3 имеют запись в таблице Attendant_Event. Это говорит нам о том, что число операторов со строками в сводной таблице равно 2.
  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 вместо двух, которые я ищу.

Что я делаю не так?

0
Jacobo 15 Апр 2019 в 01:01

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 из которых с событиями YES для двух активных участников и 1 ряд с событиями NO.

Таким образом, вы должны учитывать только различные значения:

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
0
shukshin.ivan 14 Апр 2019 в 22:18

Вы можете сначала выбрать идентификаторы оператора с соответствующими ДА / НЕТ, а затем считать их, например:

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
Knut Forkalsrud 14 Апр 2019 в 22:16