2017-09-29 4 views
3

Ich habe derzeit:Wie Verwenden von SUM über GROUP BY in SQL Server?

SELECT Name, COUNT(*) as Total 
FROM DataTable 
WHERE Name IN ('A', 'B', 'C') 
GROUP BY Name 

resultierenden Ausgang:

Name Total 
-------------- 
A  2 
B  5 
C  3 

Stattdessen mag ich dies:

Name Total 
-------------- 
A  10 
B  10 
C  10 

Hier 10 ist insgesamt 2 + 5 + 3 (Gesamtzahl der Datensätze mit Name = A/B/C)

Wie mache ich das?

+1

Was für 'a, diese Zahl der Anzeigen ist der Punkt ',' b' und 'c' einzeln dann? Können Sie die Logik hinter der Anforderung erklären? – Mureinik

+0

Nun, tatsächlich in einer realen Abfrage, die ich die Offset-und Limit, um nur die ersten 10 Datensätze zu holen, beim nächsten Lauf werde ich nächste 10 holen. Ich brauche die Gesamtzahl, um die Gesamtzahl der Datensätze für die Paginierung anzuzeigen. –

Antwort

7

Um das gewünschte Ergebnis erhalten Sie SUM() OVER() auf den gruppierten COUNT(*) verwenden können. Demo

SELECT Name, 
     SUM(COUNT(*)) OVER() as Total 
FROM DataTable 
WHERE Name IN ('A', 'B', 'C') 
GROUP BY Name 
+1

Irgendeine Idee, wie dies gegenüber "distinct .... count (*) over" auf einem größeren Datensatz verglichen werden würde? Pläne sehen ähnlich aus (verschobene Sortieroperatorplatzierung) auf den wirklich einfachen Beispieldaten. [dbfiddle.uk] (http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=605b51a0e0edd266c9ed2e5ec037691e) – SqlZim

+0

Vielen Dank für die Antwort, ich frage mich das gleiche in Bezug auf die Leistung. –

+0

@SqlZim Ich bin auf IPad so kann nicht testen und die Pläne anschauen. Ich stelle mir vor, dass dies vorzuziehen wäre, da es die Zeilenanzahl früher reduzieren kann. Ich stelle mir vor, dass der Plan für Ihre vielleicht so viele Zeilen wie in der ganzen Tabelle spoolen könnte? –

1

Wenn Sie alle Datensätze zu zählen und dann eine Cross-Join auf allen verschiedenen Namen

SELECT a.NAME 
    ,x.Total 
FROM DataTable a 
CROSS JOIN (
    COUNT(*) AS Total FROM DataTable 
    ) x 
GROUP BY a.NAME 
    ,x.Total 
4

Sie sich von der group by los und verwenden distinct:

select distinct Name, count(*) over() as Total 
from t 
where name in ('A', 'B', 'C') 

rextester Demo: http://rextester.com/WDMT68119

kehrt:

+------+-------+ 
| name | Total | 
+------+-------+ 
| A | 10 | 
| B | 10 | 
| C | 10 | 
+------+-------+