Підрахувати кількість записів, повернених групою по


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", час, коли група за роботами, якщо я можу отримати загальну суму.
Кен Форслунд

Відповіді:


169

Ви можете зробити обидва в одному запиті, використовуючи пункт 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). Це може бути або не бути суттєвим побічним ефектом, залежно від того, як ви обробляєте результати.
cartbeforehorse

3
Щоб повернути лише кількість записів, додайте обраний верхній (1) кількість (*) над () як ....
Guilherme Campos Hazan

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 для роботи (як-от доданий тротуар)
Bjinse

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 є необхідною частиною рішення, чого це не так.
cartbeforehorse

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}

Якщо ви використовуєте такий підхід, ви можете залишити групу BY поза зображенням - якщо припустити, що ви хочете повернути весь список (як ви могли б зробити звіт про групування там, де вам потрібно знати всю кількість елементів, які ви збираєтеся згрупувати, не маючи при цьому для відображення всього набору даних, тобто служб звітування).


Яке значення BandedItemCountточно міститиме? Чи відрізняється вона між вихідними рядками? Запитувач шукає кількість чітких рівнів групування.
Джуліан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.