Contare il numero di record restituiti per gruppo da


138

Come contare il numero di record restituiti da un gruppo per query,

Ad esempio:

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

Mi da,

1
1
2

Devo contare i record sopra per ottenere 1 + 1 + 1 = 3.


3
@LorenVS: Ma questo mi darebbe un conteggio del numero di record nella tabella. Ho bisogno di un numero di record dopo che il gruppo accade.
Chris,

3
Tuttavia, il gruppo non modifica il numero di righe. 1 + 1 + 2 (nel tuo esempio) sarà il numero di righe nella tabella. Stai cercando 3? Il numero di gruppi distinti?
LorenVS,

2
Un altro modo per formulare la domanda: come posso selezionare il numero di livelli di raggruppamento distinti per una determinata query?
Giuliano

Non è sempre ovvio il motivo per cui un utente pone una domanda, ma sono arrivato perché sto testando se una colonna in una vista è una chiave primaria candidata o chiave combinata. "seleziona il conteggio (distinto COLUMNNAME) da VIEWNAME", dove il gruppo funziona se posso ottenere un totale.
Ken Forslund il

Risposte:


170

Puoi eseguire entrambe le operazioni in una query utilizzando la clausola OVER su un altro COUNT

select
    count(*) RecordsPerGroup,
    COUNT(*) OVER () AS TotalRecords
from temptable
group by column_1, column_2, column_3, column_4

So che questa è una domanda di SQL Server, ma per riferimento: non funziona su DB / 2 (nel mio caso su IBM iSeries). Vedi il mio commento alla risposta di
Thomas

Come farei eco a quel numero contato?
McDan Garrett,

1
Questo aspetto negativo di questa soluzione è che ti dà la risposta più volte (per ogni combinazione di column_1, column_2, column_3, column_4). Questo può o meno essere un effetto collaterale significativo, a seconda di come elaborate i risultati.
cartbeforehorse,

3
Per restituire solo il numero di record, aggiungi un conteggio superiore (1) selezionato (*) su () come ....
Guilherme Campos Hazan

2
Nel mio caso l'utilizzo di TOP (1) COUNT ( ) OVER () ha avuto prestazioni di query scarse. Dato che avevo solo bisogno del conteggio dei gruppi, l'ho modificato in DISTINCT COUNT ( ) OVER () e le prestazioni della query sono migliorate notevolmente.
Joe Aldrich,

71

La soluzione più semplice è utilizzare una tabella derivata:

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

Un'altra soluzione è utilizzare un 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

La prima risposta funziona anche su DB / 2, ma per qualche motivo ha bisogno dell'aggiunta AS TMP per funzionare (come ha aggiunto Troutinator)
Bjinse,

5
@Bjinse - Alcuni DBMS richiedono che tutte le tabelle derivate abbiano un alias. Lo accetteranno tutti, quindi non farà male includerlo. Lo aggiungerò alla mia risposta.
Thomas,

25

So che è piuttosto tardi, ma nessuno ha suggerito questo:

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

Questo funziona almeno in Oracle - Al momento non ho altri database su cui testarlo e non ho molta familiarità con la sintassi T-Sql e MySQL.

Inoltre, non sono del tutto sicuro se sia più efficiente nel parser farlo in questo modo, o se la soluzione di tutti gli altri di nidificare l'istruzione select sia migliore. Ma trovo che questo sia più elegante dal punto di vista della programmazione.


Thomas ha aggiunto la tua soluzione alla sua risposta. Comunque. Non consiglierei mai di farlo per motivi di manutenzione, le altre soluzioni sono molto più belle.
Răzvan Flavius ​​Panda,

@ RăzvanFlaviusPanda 1. Perché? Cosa c'è di meglio delle altre soluzioni? L'annidamento di SQL è più dettagliato e, ai miei occhi, più disordinato e più difficile da capire (ergo più difficile da mantenere in un senso di supporto). Capisco che potresti avere una preferenza per gli altri modi, ma questo non è un motivo per "raccomandarlo" rispetto alle preferenze di qualcun altro. Thomas ha fatto un suggerimento simile, sì, ma ancora una volta sembra che l'annidamento di SQL sia una parte necessaria della soluzione, che non lo è.
cartbeforehorse

12

Stavo cercando di ottenere lo stesso senza subquery e sono stato in grado di ottenere il risultato richiesto come di seguito

SELECT DISTINCT COUNT(*) OVER () AS TotalRecords
FROM temptable
GROUP BY column_1, column_2, column_3, column_4

4

Un CTE ha funzionato per me:

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

select COUNT(col1)
from cte;

3

Che ne dite di:

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

1

Potresti fare:

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

In PostgreSQL questo funziona per me:

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

1

Puoi eseguire il seguente codice qui sotto. Ha funzionato in Oracle.

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

1
Impossibile eseguire l'aggregazione all'interno di un aggregato su SQL Server.
A. Greensmith,

0

puoi anche ottenere dalla query qui sotto

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

Di seguito per PrestoDb , dove FirstField può avere più valori:

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

Che ne dite di usare una funzione di partizionamento COUNT OVER (PARTITION BY {colonna per raggruppare per}) in SQL Server?

Ad esempio, se si desidera raggruppare le vendite dei prodotti per ItemID e si desidera un conteggio di ciascun ItemID distinto, utilizzare semplicemente:

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

Se usi questo approccio, puoi lasciare il GROUP BY fuori dall'immagine - supponendo che tu voglia restituire l'intero elenco (come potresti fare un report banding in cui devi conoscere l'intero conteggio degli elementi che stai per fasciare senza avere per visualizzare l'intero set di dati, ad esempio Reporting Services).


Quale valore BandedItemCountconterrà esattamente? Differisce tra le righe di output? Il richiedente sta cercando il numero di livelli di raggruppamento distinti.
Giuliano
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.