Подсчет с внешними объединениями возвращает только те данные, из которых количество не равно нулю - PullRequest
0 голосов
/ 03 сентября 2018

Скажем, у меня есть две таблицы: user и diary.

select count(id)
from user
where is_tester is false

Здесь первичные ключи всегда называются id. Этот запрос выше дает мне около 270000, что означает, что у меня около 270000 пользователей. Теперь я хотел бы знать, сколько дневников у каждого пользователя. Итак, я пошел:

select u.id as user_id, u.dm_type, count(d.id) as bg_count
from diary as d
right join (
    select id, dm_type
    from user
    where is_tester is false
) as u
on d.user_id = u.id
where d.glucose_value > 0
group by u.id, u.dm_type

Каждый пользователь может иметь только один вид dm_type. Я ожидаю, что он скажет мне, сколько дневников у каждого пользователя, и если у него нет дневника, он даст мне NA или 0, так как я использовал right join. Однако возвращенная таблица имеет только около 75000 строк, и у каждого пользователя в этой таблице есть по крайней мере один дневник. Это не то, что я хочу. Почему это происходит и как я должен делать это правильно?

Я сослался на Объединение ПРАВАЯ СОЕДИНЕНИЕ с COUNT и подсчет одного конкретного поля в соответствии с предложением из принятого ответа.


Редактирует по комментариям:

user

| id | dm_type | is_tester |
|----|---------|-----------|
| 1  | 1       | False     |
| 2  | 1       | False     |
| 3  | 2       | False     |
| 4  | no      | False     |
| 5  | 2       | True      |

diary

| id | user_id | glucose_value |
|----|---------|---------------|
| 1  | 1       | -2            |
| 2  | 1       | 80            |
| 3  | 2       | 78            |
| 4  | 2       | 100           |
| 5  | 4       | 83            |
| 6  | 5       | 90            |

Ожидаемый результат:

| user_id | dm_type | bg_count |
|---------|---------|----------|
| 1       | 1       | 1        |
| 2       | 1       | 2        |
| 3       | 2       | 0        |
| 4       | no      | 1        |

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Проблема с вашим запросом - предложение where. Он отфильтровывает непревзойденные дневники из внешнего объединения.

Когда вы подходите к этому типу проблемы, я настоятельно рекомендую left join более right join. Это означает «сохранить все строки в первой таблице, даже если во второй ничего не совпадает». Обычно это легче выполнить, чем «хранить все строки в любой таблице в конце предложения from, но я еще не видел».

Следующее правило заключается в том, что условия в таблице first входят в предложение where, поскольку они действительно фильтруют строки. Условия для второй таблицы указаны в предложении on. Они не фильтруют строки, но используются для сопоставления.

Итак, вы можете сформулировать свой запрос как:

select u.id as user_id, u.dm_type, count(d.id) as bg_count
from user u left join
     diary d
     on d.user_id = u.id and d.glucose_value > 0
where u.is_tester is false
group by u.id, u.dm_type;

Подзапрос не требуется.

0 голосов
/ 03 сентября 2018

Попробуйте с левым соединением, он даст вам всех пользователей, есть ли у них счет дневника или нет Если у какого-либо пользователя нет дневника, он даст вам ноль

select u.id as user_id, u.dm_type, count(d.id) as bg_count from
(select id, dm_type from user where is_tester is false)u
left join diary d on d.user_id = u.id and d.glucose_value > 0
group by u.id, u.dm_type
...