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

그러나 DISTINCT 올바르게 3을 반환,이 결과 세트에서 10 개 개의 레코드가 있으며, DENSE_RANK가 올바르게 레이블을 1, 2하고, 3

내 문제는 paginationTotalRows이 여전히 10 (원래 중복 포함) 결과 집합 개수를 반환합니다. paginationTotalRows이 올바른 금액을 반환하도록 쿼리를 수정하려면 어떻게해야합니까? 상위 쿼리에서 MAX(paginationRowNo)을 찾을

+0

사용중인 SQL Server 버전은 무엇입니까? –

+0

@Used_By_Already, 2005 – epoch

+0

나는 이것을 위해 row_number()를 제안 해주십시오. –

답변

2

이동합니다 select distinct 외부 윈도우 기능. 또한 dense_rank() 대신 row_number()를 사용하는 것이 좋습니다.

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()을 사용하십시오. [please]

+0

ROW_NUMBER로 DENSE_RANK을 (를) 사용하는 Im은 DISTINCT와 작동하지 않습니다. http://blog.jooq.org/2013/10/09/sql-trick-row_number-is-to-select-what-dense_rank-is-to-select-distinct/ – epoch

+0

고맙습니다. 업데이트를 읽었습니다. 테스트 해 보겠습니다. – epoch

+0

별 모양을 선택하면 밖으로 이동하면됩니다. –

2

시도 :

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

+0

@epoch valex의 대답은 내 것과 거의 같았습니다. 그래서 나는 그 답에 많은 것을 더하고 있지 않았습니다. 나는 또한 당신이 나의 대답 –

+0

@ t-clausen.dk을 읽을 충분한 점수를 가지고 있음을 보았다. 어쨌든 고맙다! 나는이 하나에 길을 잃은 줄 알았는데 :) – epoch