Вы можете использовать количество аналитических / оконных функций без каких-либо разделов:
SELECT users.id as user_id, COUNT(*) as houses_sold,
COUNT(*) OVER() as total_count -- count of rows returned by query
FROM users
JOIN users_with_house_permissions hp ON hp.user_id = users.id
LEFT JOIN houses on houses.user_id = users.id AND houses.sold_at IS NOT NULL
GROUP BY users.id
Работает как любая другая аналитическая функция;он рассчитывает на раздел, но если не указан раздел, то он учитывается на весь набор данных.В этом случае подсчет выполняется после группировки, поэтому count(*)
подсчитывает количество элементов в группе, count(*) over()
подсчитывает количество групп в наборе данных
Кто-то еще отправил sum(count(*)) over()
, который является эффективным эквивалентом подсчета строк до их группировки.Если у вас был набор данных «кто продал дом», и он получился таким:
john
john
john
mary
4 дома были проданы, Джон продан 3, Мэри продана 1. В агентстве работают 2 торговых представителя..
COUNT(*) FROM ... GROUP BY name
дает «Джон продал 3, Мэри продал 1» и приводит к набору данных:
john, 3
mary, 1
Если бы мы подсчитали это количество, у нас было бы 4т.е. 3 + 1.Это фактически количество домов до того, как группировка была сделана.SUM(COUNT(*)) OVER()
отсюда количество строк, которые у нас были до того, как мы создали группу.Важно иметь в виду, что COUNT (*) принадлежит GROUP BY и станет целым числом, которое впоследствии будет СУММЕРЕНО СУММОЙ.Вероятно, было бы легче увидеть, если бы мы использовали подзапрос:
SELECT name, the_count, SUM(the_count) OVER()
FROM (SELECT name, count(*) as the_count FROM sales GROUP BY name) subquery
Но поскольку аналитика рассчитывается после того, как группирование выполнено, на самом деле нет необходимости представлять его таким образом;БД будет делать это так же, как и:
SELECT name, count(*), sum(count(*)) over() FROM sales GROUP BY name
Таким образом, мы дойдем до того момента, когда вы оцените, что аналитика применяется после выполнения группировки, это означает, что где COUNT(*) OVER()
счетчик количества строк в наборе данных после завершения операции группировки.Группировка произвела john,3|mary,1
, поэтому COUNT (*) OVER () это производит 2 - количество строк в наборе данных
Документация, если вы хотите прочитать больше, называется «Функции Windows» и может бытьнашел где-то как здесь: https://www.postgresql.org/docs/9.1/tutorial-window.html
Это для PG 9.1;не забудьте изменить вид на конкретную версию PG