select c.id, count(*) as 'Transactions' from voucher v
right join consumer c on v.consumer_id = c.id
where v.voucher_state in ('REDEEMED', 'EXPIRED') and c.country = 'INDIA'
group by c.id;
Ожидаемый результат: -
Идентификационные транзакции
3 0
4 0
6 3
7 9
8 4
9 0
Токовый выход: -
Идентификационные транзакции
6 3
7 9
8 4
Как выбрать строки, у которых есть count = 0? Благодарю.
Вы должны использовать LEFT JOIN
, помещать таблицу consumer
на левую сторону и перемещать
v.voucher_state in ('REDEEMED', 'EXPIRED'):
в положение ON
:
select c.id, count(v.consumer_id) as 'Transactions'
from consumer c
left join voucher v on v.consumer_id = c.id on v.voucher_state in ('REDEEMED', 'EXPIRED')
where c.country = 'INDIA'
group by c.id;
Вышеприведенный запрос возвращает все значения customer.id
удовлетворяющие условию
customer.country = 'INDIA'
Только клиенты, имеющие соответствующую запись в таблице voucher
с
voucher.voucher_state in ('REDEEMED', 'EXPIRED')
будут подсчитаны.
Поскольку вы используете RIGHT JOIN
, условие фильтрации на левой таблице должно быть в предложении ON
. Причина в том, что фильтрация произойдет до того, как оптимизатор присоединяет ее к правой таблице. Предложение WHERE
будет фильтровать в конечном результате.
Другое дело, вы должны считать только строки в левой таблице (например, COUNT(v.consumer_id))
), а не COUNT(*)
, иначе всегда будет один счетчик для каждого c.id
select c.id, count(v.consumer_id) as 'Transactions'
from voucher v
right join consumer c
on v.consumer_id = c.id
and v.voucher_state in ('REDEEMED', 'EXPIRED')
where c.country = 'INDIA'
group by c.id;
использовать IFNULL
select c.id,IFNULL(COUNT(*), 0) as 'Transactions' from voucher v
right join consumer c on v.consumer_id = c.id
where v.voucher_state in ('REDEEMED', 'EXPIRED') and c.country = 'INDIA'
group by c.id;