2009-07-27 4 views
0

Existe-t-il une méthode plus efficace pour effectuer le SQL suivant?Sélectionnez TOP N et définissez la variable si davantage peut être sélectionné.

Je veux sélectionner les 50 meilleurs résultats, mais je veux aussi définir une variable pour me dire si je serais de retour obtenu plus de résultats sans le TOP

DECLARE @MoreExists BIT 
SET @MoreExists = 0 

DECLARE @Count INT 
SELECT @Count = Count(*) 
    FROM MyTable WHERE ... --some expensive where clause 

IF @Count > 50 
    SET @MoreExists = 1 

SELECT TOP 50 Field1, Field2, ... 
    FROM MyTable WHERE ... --same expensive where clause 

Répondre

5

Sélectionnez 51 résultats à la place, utilisez le haut 50 dans la couche client, et utilisez le compte pour savoir s'il y en a plus.

+0

hm .. c'est la manière la plus évidente et la plus simple de le faire. Passez mon procès stocké le compte que je suis attendu, puis dans le SP augmenter ce nombre par un, et dans le code vérifier si le nombre renvoyé est supérieur à ce que j'ai demandé. – Ray

0

Oui.

L'approche commune est d'utiliser ROW_NUMBER():

WITH MyTableEntries AS 
( 
    SELECT ROW_NUMBER() OVER (ORDER BY Date DESC) AS Row, col1, col2 
    FROM MyTable 
    WHERE 
      -- some expensive WHERE clause 
) 
SELECT col1, col2 
FROM MyTableEntries 
WHERE Row BETWEEN(@PageIndex - 1) * @PageSize + 1 and @PageIndex*@PageSize 

L'approche efficace montré à ce SqlServercentral article:

DECLARE @startRow INT ; SET @startrow = 50 
;WITH cols 
AS 
(
    SELECT table_name, column_name, 
     ROW_NUMBER() OVER(ORDER BY table_name, column_name) AS seq, 
     ROW_NUMBER() OVER(ORDER BY table_name DESC, column_name desc) AS totrows 
    FROM [INFORMATION_SCHEMA].columns 
) 
SELECT table_name, column_name, totrows + seq -1 as TotRows 
FROM cols 
WHERE seq BETWEEN @startRow AND @startRow + 49 
ORDERBY seq 
+0

... et nécessite une inscription à sqlservercentral ... –

+0

@Sam Safran: bon point. Je vais réparer. Toutes mes excuses! –

+0

http://www.bugmenot.com/view/sqlservercentral.com – Ray

2

Un spin sur @Dougs répondre

SET NOCOUNT ON 

SELECT TOP 51 Field1, Field2, ... 
    into #t 
    FROM MyTable WHERE ... --same expensive where clause 

if @@rowcount > 50 
     SET @MoreExists = 1 

SET NOCOUNT OFF 

SELECT TOP 50 Field1, Field2, ... 
    from #t 
    -- maintain ordering with an order by clause 
+0

en utilisant une table var sera un peu mieux ... –

0

Comment à propos de l'utilisation de COUNT (*) OVER ... dans une sous-requête?

DECLARE @ReqCount int; 
SET @ReqCount = 50; 

SELECT TOP (@ReqCount) * 
FROM 
(
SELECT *, Count(*) OVER() AS TotalCnt 
FROM MyTable WHERE ... 
) t 
ORDER BY ... 
; 

Et si vous voulez utiliser ROW_NUMBER() aussi, essayez:

SELECT * 
FROM 
(
SELECT *, ROW_NUMBER() OVER (ORDER BY ...) AS RowNum, Count(*) OVER() AS TotalCnt 
FROM MyTable WHERE ... 
) t 
WHERE RowNum BETWEEN @StartRange AND @EndRange 
ORDER BY ... 
; 

Et vous pouvez facilement vérifier si TotalCnt> @ReqCount (ou @EndRange), pour être en mesure pour voir s'il y a plus à chercher.

Rob

Questions connexes