Начиная с вашего рабочего запроса
SELECT ifnull(t.diapason,'total') as diapason,
COUNT(DISTINCT user_id) AS user_count
FROM ...
Вы можете включить total_visitors
с подзапросом:
SELECT ifnull(t.diapason,'total') as diapason,
COUNT(DISTINCT user_id) * 100 /
(SELECT COUNT(distinct user_id)
FROM activity WHERE ...) as percent_of_users
FROM (...) t
GROUP BY diapason WITH ROLLUP
ORDER BY percent_of_users DESC
В качестве альтернативы, вы можете использовать join
(что ближе к структуре запроса, которую вы намеревались):
SELECT t1.diapason,
t1.user_count * 100 / tv.total_users as percent_of_users
FROM ( SELECT ifnull(t.diapason,'total') as diapason,
COUNT(distinct user_id) AS user_count
FROM ...
) as t1
CROSS JOIN (SELECT COUNT(distinct user_id) as total_visitors
FROM activity WHERE ...) as tv
ORDER BY percent_of_users DESC
Я использовал ваши псевдонимы t1
и t
, чтобы отметить, к какой части вашего запроса относится.
В обоих случаях общее количество будет рассчитываться только один раз, тем не менее, MySQL выполнит два запроса немного по-разному (хотя это не должно иметь большого эффекта). Возможно, вы захотите включить проверку на счет 0
(и, следовательно, деление на 0
), хотя здесь этого не должно быть.
Примечание: для MySQL 8+ вы можете немного упростить (и уточнить) свой код, если используете cte , поскольку в настоящее время вы в основном повторяете код подзапроса a
дважды (один раз в Ваш фактический запрос, один раз при расчете общего количества), который может вызвать раздражение и замешательство, если он сложнее простого where
.