Подсчитать количество записей, возвращаемых группой

138

Как подсчитать количество записей, возвращаемых группой по запросу,

Например:

select count(*) 
from temptable
group by column_1, column_2, column_3, column_4

Дает мне,

1
1
2

Мне нужно посчитать вышеупомянутые записи, чтобы получить 1 + 1 + 1 = 3.

Крис
источник
3
@LorenVS: Но это подсчитало бы количество записей в таблице. Мне нужно количество записей после того, как группа произойдет.
Крис
3
Группировка по не меняет количество строк. 1 + 1 + 2 (в вашем примере) будет количеством строк в таблице. Вы ищете 3? Количество отдельных групп?
LorenVS
2
Другой способ сформулировать вопрос: как выбрать количество различных уровней группировки для данного запроса?
Джулиан
Не всегда очевидно, почему пользователь задает вопрос, но я попал сюда, потому что я проверяю, является ли столбец в представлении кандидатом первичного ключа или комбинированного ключа. Тайм-аут "выберите количество (отличное от COLUMNNAME) из VIEWNAME", когда сгруппируйте по работам, если я смогу получить общее количество.
Кен Форслунд

Ответы:

170

Вы можете сделать оба в одном запросе, используя предложение OVER в другом COUNT

select
    count(*) RecordsPerGroup,
    COUNT(*) OVER () AS TotalRecords
from temptable
group by column_1, column_2, column_3, column_4
ГБН
источник
Я знаю, что это вопрос SQL-сервера, но для справки: это не работает в DB / 2 (в моем случае в IBM iSeries). Смотрите мой комментарий в ответ
Томаса
Как бы я повторил это подсчитанное число?
Макдан Гарретт
1
Недостатком этого решения является то, что оно дает вам ответ несколько раз (для каждой комбинации column_1, column_2, column_3, column_4). Это может быть или не быть значительным побочным эффектом, в зависимости от того, как вы обрабатываете результаты.
конюшня
3
Чтобы вернуть только количество записей, добавьте число избранных сверху (1) над (*) над () как ....
Гильерме Кампос Хазан
2
В моем случае использование TOP (1) COUNT ( ) OVER () имело низкую производительность запросов. Поскольку мне нужно было только количество групп, я изменил его на DISTINCT COUNT ( ) OVER (), и производительность запросов значительно улучшилась.
Джо Олдрич
71

Самое простое решение - использовать производную таблицу:

Select Count(*)
From    (
        Select ...
        From TempTable
        Group By column_1, column_2, column_3, column_4
        ) As Z

Другое решение заключается в использовании Count Distinct:

Select ...
    , ( Select Count( Distinct column_1, column_2, column_3, column_4 )
        From TempTable ) As CountOfItems
From TempTable
Group By column_1, column_2, column_3, column_4
Томас
источник
Первый ответ также работает в DB / 2, но по какой-то причине для его работы требуется добавление AS TMP (например, добавлен troutinator)
Bjinse 13.12.12
5
@Bjinse - некоторые СУБД требуют, чтобы все производные таблицы имели псевдоним. Они все примут это, так что не повредит включить это. Я добавлю это к моему ответу.
Томас
25

Я знаю, что уже поздно, но никто не предложил это:

select count ( distinct column_1, column_2, column_3, column_4) 
from   temptable

По крайней мере, это работает в Oracle - у меня нет других баз данных для тестирования, и я не очень знаком с синтаксисом T-Sql и MySQL.

Кроме того, я не совсем уверен, является ли более эффективным в синтаксическом анализаторе, чтобы сделать это таким образом, или же лучше, если все остальные решают вложить оператор select. Но я считаю это более элегантным с точки зрения кодирования.

cartbeforehorse
источник
Томас добавил ваше решение к своему ответу. Тем не мение. Я бы не советовал делать это по причинам обслуживания, другие решения гораздо приятнее.
Разван Флавиус Панда
@ RăzvanFlaviusPanda 1. Почему? Что хорошего в других решениях? Вложенный SQL более многословен и, на мой взгляд, более запутан и труден для понимания (поэтому его сложнее поддерживать в смысле поддержки). Я понимаю, что у вас могут быть предпочтения другим путям, но это не повод, чтобы «рекомендовать» это кому-то другому. Да, Томас сделал подобное предложение, но опять же он заставляет его выглядеть так, как будто вложение SQL является необходимой частью решения, а это не так.
телега верховая лошадь
12

Я пытался добиться того же без подзапроса и смог получить требуемый результат, как показано ниже

SELECT DISTINCT COUNT(*) OVER () AS TotalRecords
FROM temptable
GROUP BY column_1, column_2, column_3, column_4
Маниш Мулани
источник
4

У меня CTE работал:

with cte as (
  select 1 col1
  from temptable
  group by column_1
)

select COUNT(col1)
from cte;
SQL Пит
источник
3

Как насчет:

SELECT count(column_1)
FROM
    (SELECT * FROM temptable
    GROUP BY column_1, column_2, column_3, column_4) AS Records
PedroC88
источник
1

Вы могли бы сделать:

select sum(counts) total_records from (
    select count(*) as counts
    from temptable
    group by column_1, column_2, column_3, column_4
) as tmp
troutinator
источник
1

В PostgreSQL это работает для меня:

select count(count.counts) 
from 
    (select count(*) as counts 
     from table 
     group by concept) as count;
Omar
источник
1

Можете ли вы выполнить следующий код ниже. Это работало в Oracle.

SELECT COUNT(COUNT(*))
FROM temptable
GROUP BY column_1, column_2, column_3, column_4
Arif
источник
1
Невозможно запустить агрегат внутри агрегата на sql-сервере.
А. Гринсмит
0

Вы также можете получить по запросу ниже

select column_group_by,count(*) as Coulm_name_to_be_displayed from Table group by Column;

-- For example:
select city,count(*) AS Count from people group by city
Нитиш Саху
источник
0

Попробуйте этот запрос:

select top 1 TotalRows = count(*) over () 
from yourTable
group by column1, column2
Маримуту Шанмугасундарам
источник
0

Следуя за PrestoDb , где FirstField может иметь несколько значений:

select *
            , concat(cast(cast((ThirdTable.Total_Records_in_Group * 100 / ThirdTable.Total_Records_in_baseTable) as DECIMAL(5,2)) as varchar), '%') PERCENTage
from 
(
    SELECT FirstTable.FirstField, FirstTable.SecondField, SecondTable.Total_Records_in_baseTable, count(*) Total_Records_in_Group
    FROM BaseTable FirstTable
    JOIN (
            SELECT FK1, count(*) AS Total_Records_in_baseTable 
            FROM BaseTable
            GROUP BY FK1
        ) SecondTable
    ON FirstTable.FirstField = SecondTable.FK1
    GROUP BY FirstTable.FirstField, FirstTable.SecondField, SecondTable.Total_Records_in_baseTable
    ORDER BY FirstTable.FirstField, FirstTable.SecondField
) ThirdTable
SUKUMAR S
источник
-1

Как насчет использования функции разделения COUNT OVER (PARTITION BY {столбец для группировки по}) в SQL Server?

Например, если вы хотите сгруппировать продажи товара по ItemID и хотите подсчитать каждый отдельный ItemID, просто используйте:

SELECT
{columns you want} ,
COUNT(ItemID) OVER (PARTITION BY ItemID) as BandedItemCount ,
{more columns you want}... ,
FROM {MyTable}

Если вы используете этот подход, вы можете оставить GROUP BY вне изображения - при условии, что вы хотите вернуть весь список (как вы могли бы сделать группировку отчета, где вам нужно знать все количество элементов, которые вы собираетесь объединить, не имея для отображения всего набора данных, т. е. служб отчетов).

Джонни Б
источник
Какое значение будет BandedItemCountсодержать именно? Отличается ли он между выходными строками? Аскер ищет количество различных уровней группировки.
Джулиан