2013-10-01 51 views
10

我有一個搜索屏幕,用戶有5個過濾器可供搜索。
我一次構建了一個基於這些過濾器值和第10頁結果的動態查詢。
這工作正常SQL2012使用OFFSETFETCH,但我使用兩個查詢這樣做。在尋呼時獲取總行數

我想顯示10個結果顯示查詢找到的總行數(比方說1000)。
目前我通過運行查詢兩次 - 一次爲總計數,然後再次頁10行。
有沒有更有效的方法來做到這一點?

回答

19

您不必運行查詢兩次。

SELECT ..., total_count = COUNT(*) OVER() 
FROM ... 
ORDER BY ... 
OFFSET 120 ROWS 
FETCH NEXT 10 ROWS ONLY; 

基於the chat,看來你的問題是有點複雜 - 你申請DISTINCT的結果,除了分頁。這可能會很難確定COUNT()應該是什麼樣子以及它應該放在哪裏。這裏有一種方法(我只是想證明這一點,而不是試圖整合該技術到您從聊天更復雜的查詢):

USE tempdb; 
GO 
CREATE TABLE dbo.PagingSample(id INT,name SYSNAME); 

-- insert 20 rows, 10 x 2 duplicates 
INSERT dbo.PagingSample SELECT TOP (10) [object_id], name FROM sys.all_columns; 
INSERT dbo.PagingSample SELECT TOP (10) [object_id], name FROM sys.all_columns; 

SELECT COUNT(*) FROM dbo.PagingSample; -- 20 

SELECT COUNT(*) FROM (SELECT DISTINCT id, name FROM dbo.PagingSample) AS x; -- 10 

SELECT DISTINCT id, name FROM dbo.PagingSample; -- 10 rows 

SELECT DISTINCT id, name, COUNT(*) OVER() -- 20 (DISTINCT is not computed yet) 
FROM dbo.PagingSample 
ORDER BY id, name 
OFFSET (0) ROWS FETCH NEXT (5) ROWS ONLY; -- 5 rows 

-- this returns 5 rows but shows the pre- and post-distinct counts: 
SELECT PostDistinctCount = COUNT(*) OVER() -- 10, 
    PreDistinctCount -- 20, 
    id, name 
FROM 
(
    SELECT DISTINCT id, name, PreDistinctCount = COUNT(*) OVER() 
    FROM dbo.PagingSample 
    -- INNER JOIN ... 
) AS x 
ORDER BY id, name 
OFFSET (0) ROWS FETCH NEXT (5) ROWS ONLY; 

清理:

DROP TABLE dbo.PagingSample; 
GO 
+0

這隻適用於在動態查詢中,如果我將變量名稱作爲@oTotalRecords = COUNT(1)OVER(),它就是說「必須聲明標量變量」@oTotalRecords「。請問我可以告訴我如何修復它 – user788312

+0

我正在將值讀入一個變量並從應用程序中讀取該值 – user788312

+0

我可以從sql本身將它變成一個變量嗎 – user788312

1

你可以嘗試這樣的事情

SELECT TOP 10 * FROM 
(
    SELECT COUNT(*) OVER() TOTALCNT, T.* 
    FROM TABLE1 T 
    WHERE col1 = 'somefilter' 
) v 

SELECT * FROM 
(
    SELECT COUNT(*) OVER() TOTALCNT, T.* 
    FROM TABLE1 T 
    WHERE col1 = 'somefilter' 
) v 
ORDER BY COL1 
OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY 

現在你有總數在totalcnt列,您可以使用此欄,顯示的行總數

+0

問題是存在有一個獨特的,所以它的邏輯有點複雜。在同一級別,COUNT()OVER()將在DISTINCT之前計算。 –

1

我希望我在這個問題上還不遲,但我今晚遇到了類似的問題。由於前面的開發人員正在刪除DISTINCT並僅執行表聯接的SELECT計數(*),所以我有一個分頁類,它已經超過了返回的結果數量。雖然這並沒有解決2的查詢問題,我結束了使用嵌套查詢,以便它看起來像這樣:

原始查詢

SELECT DISTINCT 
    field1, field2 
FROM 
    table1 t1 
    left join table2 t2 on t2.id = t1.id 

過度膨脹結果查詢

SELECT 
    count(*) 
FROM 
    table1 t1 
    left join table2 t2 on t2.id = t1.id 

我的結果查詢解決方案

SELECT 
    count(*) 
FROM 
    (SELECT DISTINCT 
    field1, field2 
    FROM 
    table1 t1 
    left join table2 t2 on t2.id = t1.id) as tbl; 
2

我的解決方案類似於「rs。answer」

DECLARE @PageNumber AS INT, @RowspPage AS INT 
SET @PageNumber = 2 
SET @RowspPage = 5 

SELECT COUNT(*) OVER() totalrow_count,* 
    FROM databasename 
    where columnname like '%abc%' 
    ORDER BY columnname 
    OFFSET ((@PageNumber - 1) * @RowspPage) ROWS 
    FETCH NEXT @RowspPage ROWS ONLY; 

返回結果將包括totalrow_count作爲第一列名