Zählen Sie die Anzahl der Datensätze, die von der Gruppe zurückgegeben wurden


138

Wie zähle ich die Anzahl der Datensätze, die von einer Gruppe per Abfrage zurückgegeben wurden?

Zum Beispiel:

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

Gibt mir,

1
1
2

Ich muss die obigen Datensätze zählen, um 1 + 1 + 1 = 3 zu erhalten.


3
@ LorenVS: Aber das würde mir eine Zählung der Anzahl der Datensätze in der Tabelle geben. Ich benötige die Anzahl der Datensätze, nachdem die Gruppe passiert ist.
Chris

3
Die Gruppe nach ändert jedoch nicht die Anzahl der Zeilen. 1 + 1 + 2 (in Ihrem Beispiel) ist die Anzahl der Zeilen in der Tabelle. Suchen Sie 3? Die Anzahl der unterschiedlichen Gruppen?
LorenVS

2
Eine andere Möglichkeit, die Frage zu formulieren: Wie wähle ich die Anzahl der unterschiedlichen Gruppierungsebenen für eine bestimmte Abfrage aus?
Julian

Es ist nicht immer offensichtlich, warum ein Benutzer eine Frage stellt, aber ich bin hierher gekommen, weil ich teste, ob eine Spalte in einer Ansicht ein Kandidaten-Primärschlüssel oder ein Kombinationsschlüssel ist. Das Zeitlimit für "Select Count (eindeutiger COLUMNNAME) von VIEWNAME" ist abgelaufen, wobei "Gruppieren nach" funktioniert, wenn ich eine Gesamtsumme erhalten kann.
Ken Forslund

Antworten:


169

Sie können beides in einer Abfrage mit der OVER-Klausel in einem anderen COUNT ausführen

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

Ich weiß, dass dies eine SQL Server-Frage ist, aber als Referenz: Dies funktioniert nicht unter DB / 2 (in meinem Fall unter IBM iSeries). Siehe meinen Kommentar bei Thomas 'Antwort
Bjinse

Wie würde ich diese gezählte Zahl wiedergeben?
McDan Garrett

1
Der Nachteil dieser Lösung ist, dass Sie die Antwort mehrmals erhalten (für jede Kombination von column_1, column_2, column_3, column_4). Dies kann eine signifikante Nebenwirkung sein oder auch nicht, je nachdem, wie Sie die Ergebnisse verarbeiten.
Cartbeforehorse

3
Um nur die Anzahl der Datensätze zurückzugeben, fügen Sie eine ausgewählte Top (1) Anzahl (*) über () als ....
Guilherme Campos Hazan

2
In meinem Fall hatte die Verwendung von TOP (1) COUNT ( ) OVER () eine schlechte Abfrageleistung. Da ich nur die Anzahl der Gruppen benötigte, änderte ich dies in DISTINCT COUNT ( ) OVER (), und die Abfrageleistung verbesserte sich dramatisch.
Joe Aldrich

71

Die einfachste Lösung besteht darin, eine abgeleitete Tabelle zu verwenden:

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

Eine andere Lösung ist die Verwendung eines 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

Die erste Antwort funktioniert auch auf DB / 2, aber aus irgendeinem Grund benötigt es den Zusatz AS TMP, um zu funktionieren (wie Forelleinator hinzugefügt)
Bjinse

5
@Bjinse - Einige DBMS erfordern, dass alle abgeleiteten Tabellen einen Alias ​​haben. Sie alle werden es akzeptieren, damit es nicht schadet, es aufzunehmen. Ich werde es meiner Antwort hinzufügen.
Thomas

25

Ich weiß, dass es ziemlich spät ist, aber niemand hat dies vorgeschlagen:

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

Dies funktioniert zumindest in Oracle - ich habe derzeit keine anderen Datenbanken zum Testen und bin mit der T-Sql- und MySQL-Syntax nicht so vertraut.

Ich bin mir auch nicht ganz sicher, ob es im Parser effizienter ist, dies auf diese Weise zu tun, oder ob die Lösung aller anderen, die select-Anweisung zu verschachteln, besser ist. Aber ich finde, dass dies aus Codierungssicht eleganter ist.


Thomas fügte Ihrer Antwort Ihre Lösung hinzu. Wie auch immer. Ich würde dies aus Wartungsgründen niemals empfehlen, die anderen Lösungen sind viel besser.
Răzvan Flavius ​​Panda

@ RăzvanFlaviusPanda 1. Warum? Was ist schöner an den anderen Lösungen? Das Verschachteln von SQL ist ausführlicher und in meinen Augen unordentlicher und schwerer zu verstehen (daher im Support-Sinne schwieriger zu pflegen). Ich verstehe, dass Sie vielleicht eine Vorliebe für die anderen Möglichkeiten haben, aber das ist kein Grund, es gegenüber der Präferenz eines anderen zu "empfehlen". Thomas hat einen ähnlichen Vorschlag gemacht, ja, aber er lässt es wieder so aussehen, als ob das Verschachteln von SQL ein notwendiger Teil der Lösung ist, was es nicht ist.
Cartbeforehorse

12

Ich habe versucht, dasselbe ohne Unterabfrage zu erreichen, und konnte das erforderliche Ergebnis wie unten erzielen

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

4

Ein CTE hat für mich funktioniert:

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

select COUNT(col1)
from cte;

3

Wie wäre es mit:

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

1

Du könntest es tun:

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 funktioniert das bei mir:

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

1

Können Sie den folgenden Code unten ausführen? Es hat in Oracle funktioniert.

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

1
Aggregat kann nicht innerhalb eines Aggregats auf einem SQL-Server ausgeführt werden.
A. Greensmith

0

Sie können auch durch die folgende Abfrage erhalten

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

Folgendes für PrestoDb , wo FirstField mehrere Werte haben kann:

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

Wie wäre es mit einer COUNT OVER-Partitionierungsfunktion (PARTITION BY {Spalte zum Gruppieren nach}) in SQL Server?

Wenn Sie beispielsweise Produktverkäufe nach ItemID gruppieren möchten und eine Zählung jeder einzelnen ItemID wünschen, verwenden Sie einfach:

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

Wenn Sie diesen Ansatz verwenden, können Sie die GROUP BY aus dem Bild herauslassen - vorausgesetzt, Sie möchten die gesamte Liste zurückgeben (da Sie möglicherweise eine Streifenbildung melden, bei der Sie die gesamte Anzahl der Elemente kennen müssen, ohne die Sie eine Band erstellen möchten um den gesamten Datensatz anzuzeigen, z. B. Reporting Services).


Welcher Wert wird BandedItemCountgenau enthalten? Unterscheidet es sich zwischen Ausgabezeilen? Der Fragesteller sucht nach der Anzahl der verschiedenen Gruppierungsebenen.
Julian
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.