Sql server 2008 r2 - избыточные строки - PullRequest
1 голос
/ 28 июля 2011

Первый запрос

   --645 rows
    SELECT  *
            FROM    (
                      SELECT DISTINCT
                                cu.*,
                                ROW_NUMBER() OVER ( ORDER BY cu.Id ) AS RowNum
                      FROM      Customers cu
                                LEFT JOIN dbo.CustomerCategories cc
                                ON cc.CustomerId = cu.Id
                                LEFT JOIN dbo.CustomerServices cs
                                 ON cs.CustomerId = cu.Id
                      WHERE     ( @FullName IS NULL
                                  OR cu.FullName LIKE @FullName
                                )
                                AND ( @CategoriesIdXml IS   NULL
                                      OR cc.CategoryId IN ( SELECT  *
                                                            FROM    @CategoriesList )
                                    )
                                AND ( @ServicesIdXml IS NULL
                                      OR cs.ServiceId IN ( SELECT   *
                                                           FROM     @ServicesList )
                                    ) 

                                    ) AS _
            WHERE   RowNum BETWEEN ( @PageIndex - 1 ) * @PageSize + 1
                           AND     @PageIndex * @PageSize

Второй запрос

 --41 rows
    SELECT  *
        FROM    (
                  SELECT DISTINCT
                            cu.*,
                            ROW_NUMBER() OVER ( ORDER BY cu.Id ) AS RowNum
                  FROM      Customers cu
                  --          LEFT JOIN dbo.CustomerCategories cc
                  --          ON cc.CustomerId = cu.Id
                  --          LEFT JOIN dbo.CustomerServices cs
                  --           ON cs.CustomerId = cu.Id
                  --WHERE     ( @FullName IS NULL
                  --            OR cu.FullName LIKE @FullName
                  --          )
                  --          AND ( @CategoriesIdXml IS   NULL
                  --                OR cc.CategoryId IN ( SELECT  *
                  --                                      FROM    @CategoriesList )
                  --              )
                  --          AND ( @ServicesIdXml IS NULL
                  --                OR cs.ServiceId IN ( SELECT   *
                  --                                     FROM     @ServicesList )
                  --              ) 

                                ) AS _
        WHERE   RowNum BETWEEN ( @PageIndex - 1 ) * @PageSize + 1
                       AND     @PageIndex * @PageSize

Второй запрос возвращает правильный набор результатов (41 строка), но первый возвращает 645 строк, что неверно. Но я использую DISTINCT в обоих запросах, и мне интересно, почему сначала возвращается слишком много строк.

Как мне этого избежать?

Ответы [ 2 ]

3 голосов
/ 28 июля 2011

DISTINCT применяется после создания ROW_NUMBER ()

Поскольку ROW_NUMBER () отличается для каждой строки, каждая строка уникальна по определению. Это означает, что у вас есть несколько вариантов.

Примените Distinct в одном запросе, затем оберните другой вокруг него для ROW_NUMBER ()

* * 1010

Используйте GROUP BY вместо DISTINCT

SELECT
  *
FROM
(
  SELECT DISTINCT
    cu.*,
    ROW_NUMBER() OVER (ORDER BY id) AS row_num
  FROM
    <your query>
  GROUP BY
    cu.id,
    cu.field1,
    cu.field2,
    etc, etc
)
  AS ordered_data
WHERE
  RowNum BETWEEN ( @PageIndex - 1 ) * @PageSize + 1
             AND   @PageIndex       * @PageSize
1 голос
/ 28 июля 2011

ROW_NUMBER не правильно, вместо этого используйте DENSE_RANK.

Здесь вы можете увидеть разницу: Разница между ROW_NUMBER, RANK и DENSE_RANK

ROW_NUMBERдаст вам другой номер для одного и того же Клиента, и это не то, что вы хотите, вам нужно то же значение, чтобы ваш индивидуальный мог работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...