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


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. Но я считаю это более элегантным с точки зрения кодирования.


Томас добавил ваше решение к своему ответу. Тем не мение. Я бы не советовал делать это по причинам обслуживания, другие решения гораздо приятнее.
Разван Флавиус Панда

@ 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;

3

Как насчет:

SELECT count(column_1)
FROM
    (SELECT * FROM temptable
    GROUP BY column_1, column_2, column_3, column_4) AS Records

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

1

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

select count(count.counts) 
from 
    (select count(*) as counts 
     from table 
     group by concept) as count;

1

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

SELECT COUNT(COUNT(*))
FROM temptable
GROUP BY column_1, column_2, column_3, column_4

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

Следуя за 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

-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содержать именно? Отличается ли он между выходными строками? Аскер ищет количество различных уровней группировки.
Джулиан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.