2014-09-22 87 views
1

我選擇的記錄可能包含重複項,我需要能夠爲不同的結果集分頁。SQL總行數(DENSE_RANK/DISTINCT)

目前,我有以下的(簡化)查詢:

SELECT pagiWrapper.* FROM (
    SELECT DISTINCT alias.id 
    , alias.name 
    , DENSE_RANK() OVER (ORDER BY alias.name ASC) AS 'paginationRowNo' 
    , COUNT(*) OVER(PARTITION BY 1) AS 'paginationTotalRows' 
     FROM MyTable alias 
     LEFT JOIN MyTableTwo alias2 ON alias2.id = alias.id 
      WHERE (/* condition */) 
) pagiWrapper WHERE pagiWrapper.paginationRowNo > 0 AND pagiWrapper.paginationRowNo <= 15 

有10個記錄在這個結果集,但是DISTINCT正確返回3,和DENSE_RANK正確標註他們123

我的問題是paginationTotalRows仍然返回10(原始重複包括)結果集計數,我如何修改查詢以便paginationTotalRows返回正確的數量?

+0

請問哪個版本的SQL Server正在使用? – 2014-09-22 09:02:56

+0

@Used_By_Already,2005 – epoch 2014-09-22 09:03:35

+0

我的確在爲此建議row_number(),請查看 – 2014-09-22 09:13:32

回答

2

移動的select distinct外的窗函數。我還建議你使用row_number()而不是dense_rank()。

SELECT 
     pagiWrapper.* 
FROM (
      SELECT 
        iq.* 
       , ROW_NUMBER() OVER (ORDER BY iq.name ASC) AS 'paginationRowNo' 
       , COUNT(*) OVER (PARTITION BY 1)   AS 'paginationTotalRows' 
      FROM (
        SELECT DISTINCT 
         alias.id 
         , alias.name 
         , alias2.something_I_hope 
        FROM MyTable alias 
         LEFT JOIN MyTableTwo alias2 
            ON alias2.id = alias.id 
        WHERE (1 = 1 /* condition */) 
       ) iq 
    ) pagiWrapper 
WHERE pagiWrapper.paginationRowNo > 0 
     AND pagiWrapper.paginationRowNo <= 15 

我推薦ROW_NUMBER()分頁。這個功能不能在一個分區內重複一個數字,如果沒有分區,它就根本不能重複一個數字。然而,DENSE_RANK()可以在任何分區內重複一個數字,如果不分區,仍然可以重複數字。要使分頁完全可預測,您需要完全可預測的行編號,因此請使用ROW_NUMBER()。 [請]

+0

我使用DENSE_RANK作爲ROW_NUMBER不適用於DISTINCT,http://blog.jooq.org/2013/10/09/sql-trick-row_number-is-to-select-what-dense_rank-is-to-select-distinct/ – epoch 2014-09-22 09:22:24

+0

謝謝你,我剛剛閱讀你的更新,我要測試它 – epoch 2014-09-22 09:23:33

+0

它確實如果你移動它在選擇不同 – 2014-09-22 09:24:08

2

試圖找到MAX(paginationRowNo)頂層查詢:

SELECT pagiWrapper.* 
     FROM(
      SELECT *, 
       MAX(paginationRowNo) OVER(PARTITION BY 1) 
        as 'paginationTotalRows' 
      FROM 
      (   
       SELECT DISTINCT alias.id 
       , alias.name 
       , DENSE_RANK() OVER (ORDER BY alias.name ASC) AS 'paginationRowNo' 
        FROM MyTable alias 
        LEFT JOIN MyTableTwo alias2 ON alias2.id = alias.id 
        WHERE (/* condition */) 
      ) as PW 
     ) pagiWrapper 
      WHERE pagiWrapper.paginationRowNo > 0 
       AND pagiWrapper.paginationRowNo <= 15 
+0

非常感謝您的答覆valex! @ t-clausen.dk,我喜歡你的解釋(不知道你爲什麼刪除了你的答案 - 無論如何,謝謝你!)。 – epoch 2014-09-22 09:05:19

+0

@epoch valex的答案與我的答案几乎相同。所以我對這個答案沒有太多的補充。我還看到你有足夠的積分閱讀我的回答 – 2014-09-22 09:11:15

+0

@ t-clausen.dk,謝謝無論如何!我以爲我是在這一個:) – epoch 2014-09-22 09:12:18