2009-03-04 6 views

Répondre

3

Souhaitez-vous une deuxième requête?

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

OU

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 
    ... 

Ou (Edit: en utilisant AVEC)

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

Je voudrais éviter une deuxième requête. Peut-être avec des tables d'instruction ou temporaires? Je ne suis pas expert en SQL Server –

+0

Les exemples 1 et 3 sont des requêtes simples et fonctionnellement identiques. – gbn

+0

Ok, je veux dire que je voudrais éviter une seconde "analyse de table". Je voudrais faire en sorte que le moteur scanne seulement une fois la table, afin de récupérer le nombre total et les n lignes. –

1

Supprimer la clause ORDER BY de la 2ème requête ainsi.

1

n °

SQL Server ne garde pas COUNT(*) dans les métadonnées comme MyISAM, il calcule chaque fois.

MISE À JOUR: Si vous avez besoin d'un devis, vous pouvez utiliser les métadonnées statistiques:

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

@primary_key est le nom de clé primaire de votre table.

Ceci retournera le COUNT(*) de la dernière mise à jour des statistiques.

+0

dites-vous dans mysql, vous pouvez faire "SELECT * FROM t_user WHERE ... LIMIT 0,20" et il y a méta-données pour le nombre total de lignes en mémoire? Alors que je n'ai pas à faire une deuxième requête avec COUNT()? – John

+0

OH, je viens de répondre à ma propre question ... SQL_CALC_FOUND_ROWS et FOUND_ROWS() fait le travail .. merci! – John

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

Cela ne ferait-il pas "SELECT COUNT (*) AS Expr1 FROM T" pour chaque ligne de sortie? Dans ce cas 10 lignes – gbn

+1

Je n'ai pas profilé cela, mais je pense que ce serait en fait plus lent car il est dans une sous-requête et retourné dans chaque ligne. Je ne suis pas un gourou cependant, le serveur pourrait être assez intelligent pour le mettre en cache. Même encore, je ne pense pas que ce serait plus rapide que deux requêtes, car il les exécute tous les deux. –

1

Ce qui est dans cette réponse semble fonctionner:

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

Fondamentalement, vous faire:

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

TotalCount aura le nombre total de lignes. Il est répertorié sur chaque ligne si.

Lorsque j'ai testé cela, le plan de requête montrait que la table n'était frappée qu'une seule fois.

Questions connexes