2009-03-04 2 views

Antwort

3

Möchten Sie eine zweite Abfrage?

SELECT TOP 10 
    *, foo.bar 
FROM 
    T 
    CROSS JOIN 
    (SELECT COUNT(*) AS bar FROM T WHERE ...) foo 
WHERE 
    ... 
ORDER BY 
    ... 

ODER

DECLARE @bar int 
SELECT @bar = COUNT(*) AS bar FROM T WHERE ... 
SELECT TOP 10 
    *, @bar 
FROM 
    T 
    CROSS JOIN 
    (SELECT COUNT(*) AS bar FROM T WHERE ...) foo 
WHERE 
    ... 
ORDER BY 
    ... 

Oder (Edit: mit MIT)

WITH cTotal AS 
(
    SELECT COUNT(*) AS bar FROM T WHERE ...) 
) 
SELECT TOP 10 
    *, cTotal .bar 
FROM 
    T 
WHERE 
    ... 
ORDER BY 
    ... 
+0

Ich möchte eine zweite Abfrage vermeiden. Vielleicht mit WITH-Anweisung oder temporären Tabellen? Ich bin kein Experte von SQL-Server –

+0

Beispiele 1 und 3 sind einzelne Abfragen und funktional identisch. – gbn

+0

Ok, ich möchte einen zweiten "Table Scan" vermeiden. Ich möchte die Engine dazu bringen, nur einmal die Tabelle zu scannen, um die Gesamtanzahl und die n Zeilen abzurufen. –

1

Entfernen Sie die ORDER BY-Klausel aus der zweiten Abfrage ebenfalls.

1

Nr

SQL Server nicht halten COUNT(*) in Metadaten wie MyISAM, es jedes Mal berechnet.

UPDATE: Wenn Sie eine Schätzung benötigen, können Sie Statistiken Metadaten verwenden:

SELECT rows 
FROM dbo.sysindexes 
WHERE name = @primary_key, 

wo @primary_key Tisch Primärschlüssel Name ist.

Dies wird die COUNT(*) vom letzten Statistikupdate zurückgeben.

+0

sagst du in mysql, können Sie tun "SELECT * FROM t_user WHERE ... LIMIT 0,20" und gibt es Metadaten für die Gesamtzahl der Zeilen im Speicher? Damit ich mit COUNT() keine zweite Abfrage machen muss? – John

+0

OH, Ich habe gerade meine eigene Frage beantwortet ... SQL_CALC_FOUND_ROWS und FOUND_ROWS() macht den Job..danke! – John

0
SELECT  TOP (2) *, 
      (SELECT COUNT(*) AS Expr1 FROM T) AS C 
FROM   T 
+0

verwendet. Würde dies nicht "SELECT COUNT (*) AS Expr1 FROM T" für jede Ausgabezeile tun? In diesem Fall 10 Zeilen – gbn

+1

Ich habe dies nicht profiliert, aber ich denke, das wäre eigentlich langsamer, da es in einer Unterabfrage ist und in jeder Zeile zurückgegeben wird. Ich bin jedoch kein Guru, der Server könnte schlau genug sein, um ihn zu cachen. Trotzdem glaube ich nicht, dass es * schneller * als zwei Abfragen wäre, da es beide weiterhin ausführt. –

1

Was in dieser Antwort scheint zu funktionieren:

https://stackoverflow.com/a/19125458/16241

Grundsätzlich

Sie tun ein:

SELECT top 100 YourColumns, TotalCount = Count(*) Over() 
From YourTable 
Where SomeValue = 32 

Totalcount wird die Gesamtzahl der Zeilen haben. Es ist jedoch in jeder Zeile aufgeführt.

Wenn ich dies getestet habe, zeigte der Abfrageplan, dass die Tabelle nur einmal getroffen wurde.

Verwandte Themen