SQL总行数(DENSE_RANK / DISTINCT)

时间:2014-09-22 08:18:05

标签: sql sql-server count ranking dense-rank

我正在选择可能包含重复项的记录,我需要能够对不同的结果集进行分页。

目前,我有以下(简化)查询:

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返回正确的数量?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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()。 [请]