2015-09-02 9 views
0

У меня есть таблица, содержащая заказы, которые могут иметь 5 разных статусов (11, 12, 14, 22, 24). Я хочу подсчитать количество статусов «12» (неудачных заказов) и разделить их на общее количество статусов (общее количество заказов).Подсчет значений конкретного значения столбца по сравнению с общим числом

Вот как моя таблица выглядит:

status_id | restaurant 
---------------------- 
11  | rest1 
11  | rest1 
12  | rest2 
12  | rest3 
12  | rest1 
14  | rest1 
24  | rest1 
22  | rest1 

Я хотел бы иметь следующий (процент в качестве примера)

status_id | restaurant | perc_of_status_id_12 
--------------------------------------------- 
11  | rest1  | 10% 
11  | rest1  | 10% 
12  | rest2  | 5% 
12  | rest3  | 11% 
12  | rest1  | 10% 
14  | rest1  | 10% 
24  | rest1  | 10% 
22  | rest1  | 10% 

Итак расчет для последнего столбца должно быть:

Count of status id 12 for restaurantX/total number of orders 

Было бы еще более совершенным, если бы оно было пропорционально общему количеству заказов для r estaurantX. Например, ресторан, получающий 1 заказ и неудачный 1, имеет коэффициент сбоя 100%, но в ресторане, принимающем 100 заказов, а в случае неудачи 5, коэффициент сбоя составляет 5%. Тем не менее, ресторан с 5 неудачными заказами должен быть приоритетным. Я действительно не знаю, как включить это в настоящий момент, возможно, назначить вес, основанный на общем количестве заказов. Если кто-то имеет представление об этом, он будет очень признателен.

с весом таблицы будет выглядеть следующим образом:

status_id | restaurant | perc_of_status_id_12 | weighted 
-------------------------------------------------------- 
11  | rest1  | 10%     | 10% * weight 
11  | rest1  | 10%     | 
12  | rest2  | 5%     | 
12  | rest3  | 11%     | 
12  | rest1  | 10%     | 
14  | rest1  | 10%     | 
24  | rest1  | 10%     | 
22  | rest1  | 10%     | 

Я пытался играть немного с COUNT, но я не могу понять это. Я попытался это:

ROUND((COUNT(CASE WHEN o.status_id = '12' THEN 1 END) * 100)::numeric/COUNT(CASE WHEN o.status_id IN ('11','12','14','22','24') THEN 1 END, 2)) AS fail_perc 

ответ

0

Используйте предложение FILTER для агрегата:

COUNT(status_id) FILTER (WHERE status_id = 12)/CAST(COUNT(status_id) AS float4) 

Для старых PostgreSQL версии вы можете использовать CASE вместо:

COUNT(CASE WHEN status_id = 12 THEN 1 END)/CAST(COUNT(status_id) AS float4) 
+0

Это не дает ошибку, но он возвращает только 1 (сбой) или 0 (не сбой). Я в основном хочу подсчитать ВСЕ вхождения идентификатора статуса 12 для ресторанаX, деленного на ВСЕ заказы в сочетании. – Mischa

+0

@ Миша Да, и вот что это делает. Подсчитывает все статус = 12 и подсчитывает все записи. Вы захотите «GROUP BY restaurant». Если вы считаете его более читаемым, вы можете использовать 'SUM' вместо' COUNT' в старом варианте 'CASE'. Если 'status_id' может быть нулевым, используйте' count (*) 'not' count (status_id) 'для знаменателя. –

+0

Благодарим вас за помощь! К сожалению, он все еще не делает то, что я хочу. Я должен добавить больше столбцов в GROUP BY из-за моего запроса. Я должен поставить следующую команду GROUP BY order_date, order_id, ресторан. Полагаю, именно по этой причине он не работает, как я хочу. – Mischa

Смежные вопросы