Меню Закрыть

Select count group by

I have an sql select query that has a group by. I want to count all the records after the group by statement. Is there a way for this directly from sql? For example, having a table with users I want to select the different towns and the total number of users

I want to have a column with all the towns and another with the number of users in all rows.

An example of the result for having 3 towns and 58 users in total is :

11 Answers 11

This will do what you want (list of towns, with the number of users in each):

You can use most aggregate functions when using GROUP BY .

Update (following change to question and comments)

You can declare a variable for the number of users and set it to the number of users then select with that.

The other way is:

If you want to order by count (sound simple but i can`t found an answer on stack of how to do that) you can do:

With Oracle you could use analytic functions:

Your other options is to use a subquery:

Ten non-deleted answers; most do not do what the user asked for. Most Answers mis-read the question as thinking that there are 58 users in each town instead of 58 in total. Even the few that are correct are not optimal.

SHOW session status LIKE ‘Handler%’;

In the OP’s context:

Since there is only one row from tot , the CROSS JOIN is not as voluminous as it might otherwise be.

The usual pattern is COUNT(*) instead of COUNT(town) . The latter implies checking town for being not null, which is unnecessary in this context.

Читайте также:  Газовая плита whirlpool acm 5131 wh 2

Хочу поделиться одним интересным решением, к которому мне удалось прийти сегодня во время оптимизации запроса поиска пользователей. В выборке необходимо было возвращать количество общих групп текущего пользователя и меня — того, кто производит поиск. Что называется total shared groups. В итоге всё поместилось в один компактный запрос без подзапросов (что очень критично, позже объясню почему) с использованием одной таблицы в FROM, без GROUP BY и HAVING.

Представим задачу более наглядно. Примем следующие таблицы:
— group (group_id)
— user (user_id)
— user_group (хранит связки user_id-group_id)

Необходимо узнать количество групп, в котором состоят пользователи user1 и user2. То есть найти пересечения между юзерами по таблице user_group.

1. Следующий запрос выдаст количество всех записей из таблицы user_group, которые принадлежат юзерам user1 и user2.
SELECT
COUNT(`group_id`)
FROM
`user_group`
WHERE
`user_id` IN (:user1,:user2)

2. А вот этот запрос выдаст количество записей из таблицы user_group, которые принадлежат юзерам user1 и user2, но с уникальным group_id:
SELECT
COUNT(DISTINCT `group_id`)
FROM
`user_group`
WHERE
`user_id` IN (:user1,:user2)

В данном случае, если нашлись такие группы, которые были привязаны сразу к двум нашим пользователям, то они будут «схлопнуты» в одну строку.

3. В итоге приходим к виду:
SELECT
COUNT(`group_id`) — COUNT(DISTINCT `group_id`)
FROM
`user_group`
WHERE
`user_id` IN (:user1,:user2)

Если отнять общее число групп двух пользователей и число групп, с учётом уникальности group_id, то в рузультате получим наше искомое total shared groups — сколько общих групп у двух пользователей.

Как ещё можно было решить задачу?
SELECT
COUNT(*)
FROM
(
SELECT
`group_id`
FROM
`user_group`
WHERE
`user_id` IN (:user1,:user2)
GROUP BY
`group_id`
HAVING
COUNT(*) > 1
) as `shared_groups`

Читайте также:  Как в экселе прибавлять дни к дате

Такой подход я встречал довольно часто. Но у него есть один существенный минус — использование подзапроса. Если :user1 или :user2 не передаются в запрос, а подставляются динамически из запроса верхнего уровня (например, какой-нибудь `user1`.`user_id`), то данный вариант выдаст ошибку.

Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.

Давайте вспомним, какие сообщения и в каких темах у нас имеются. Для этого можно воспользоваться привычным запросом:

А что, если нам надо лишь узнать сколько сообщений на форуме имеется. Для этого можно воспользоваться встроенной функцией COUNT(). Эта функция подсчитывает число строк. Причем, если в качестве аргумента этой функции выступает *, то подсчитываются все строки таблицы. А если в качестве аргумента указывается имя столбца, то подсчитываются только те строки, которые имеют значение в указанном столбце.

В нашем примере оба аргумента дадут одинаковый результат, т.к. все столбцы таблицы имеют тип NOT NULL. Давайте напишем запрос, используя в качестве аргумента столбец > SELECT COUNT(id_topic) FROM posts;

Итак, в наших темах имеется 4 сообщения. Но что, если мы хотим узнать сколько сообщений имеется в каждой теме. Для этого нам понадобится сгруппировать наши сообщения по темам и вычислить для каждой группы количество сообщений. Для группировки в SQL используется оператор GROUP BY. Наш запрос теперь будет выглядеть так:

Оператор GROUP BY указывает СУБД сгруппировать данные по столбцу id_topic (т.е. каждая тема — отдельная группа) и для каждой группы подсчитать количество строк:

Читайте также:  Windows 7 professional x64 key

Ну вот, в теме с >
Предположим, что нас интересуют только те группы, в которых больше двух сообщений. В обычном запросе мы указали бы условие с помощью оператора WHERE, но этот оператор умеет работать только со строками, а для групп те же функции выполняет оператор HAVING:

В результате имеем:

В уроке 4 мы рассматривали, какие условия можно задавать оператором WHERE, те же условия можно задавать и оператором HAVING, только надо запомнить, что WHERE фильтрует строки, а HAVING — группы.

Итак, сегодня мы узнали, как создавать группы и как подсчитать количество строк в таблице и в группах. Вообще вместе с оператором GROUP BY можно использовать и другие встроенные функции, но их мы будем изучать позже.

Видеоуроки php + mysql

Если этот сайт оказался вам полезен, пожалуйста, посмотрите другие наши статьи и разделы.

Рекомендуем к прочтению

Добавить комментарий

Ваш адрес email не будет опубликован.