2014-09-22 84 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