# #sql #google-bigquery
Вопрос:
Я пытаюсь выяснить, как подсчитать, сколько клиентов находится в каждом статусе по стране.
Я начал с объединения двух таблиц customers_customers
и customer_status
получения значений страны для каждого клиента. Это даст мне одноразовый ответ для конкретной страны и статуса. Однако я не могу понять, как подсчитать, сколько клиентов (по странам) находится в каждом статусе. (Пример желаемого результата ниже)
SELECT COUNT (customers_customers.customerID)
FROM customers_customers
LEFT JOIN customer_status
ON customers_customers.customerID = customer_status.customerID
WHERE customers_customers.Country = "US" and customer_status.status = "In Progress";
customers_customers
CustomerID | Страна |
---|---|
1 | США |
2 | CA |
3 | Великобритания |
4 | ГБ |
5 | США |
customer_status
CustomerID | Статус |
---|---|
1 | Выполняется |
2 | Выполнено |
3 | Не запущен |
4 | Выполнено |
5 | Выполняется |
В конечном счете, я ищу этот результат:
Страна | Не запущен | Выполняется | Выполнено |
---|---|---|---|
США | 2 | 3 | 1 |
Великобритания | 1 | 6 | 2 |
ГБ | 2 | 5 | 1 |
CA | 2 | 1 | 7 |
Ответ №1:
Вы можете использовать агрегатную функцию SUM by condition и group by country .
SELECT
country,
SUM(CASE WHEN cs.status = 'Not Started' THEN 1 ELSE 0 END) AS NotStarted,
SUM(CASE WHEN cs.status = 'In Progress' THEN 1 ELSE 0 END) AS InProgress,
SUM(CASE WHEN cs.status = 'Done' THEN 1 ELSE 0 END) AS Done
FROM customers_customers cc
JOIN customer_status cs ON cc.customerID = cs.customerID
GROUP BY country
Комментарии:
1. Или вы можете использовать
COUNT(*) FILTER (WHERE cs.status = 'Not Started')
вместоSUM(...)
.2. В итоге я использовал SUM (СЛУЧАЙ, КОГДА …), И это сработало! Я попытался использовать ФИЛЬТР COUNT (*), и когда я продолжал натыкаться на стену, я прочитал, что он не работает с Google BQ, который я использую. Спасибо за помощь!
3. Вы получили это! 🙂 Учимся пользоваться этим сайтом, ха-ха
Ответ №2:
select
cc.country as "Country",
count(*) filter (where cs.status = 'Not Started') as "Not Started",
count(*) filter (where cs.status = 'In Progress') as "In Progress",
count(*) filter (where cs.status = 'Done') as "Done"
from
customers_customers cc left join customer_status cs
on cc."customerID" = cs."customerID"
group by 1
Ответ №3:
Рассмотрим ниже довольно общий подход
select * from (
select * replace(replace(status, ' ', '_') as status)
from customers_customers
join customer_status
using (customerID)
)
pivot (count(customerID) for status in ('Not_Started', 'In_Progress', 'Done'))
если применяется к образцу / фиктивным данным в вашем вопросе — вывод