SQL查询 - 奇怪的行为

时间:2011-06-06 11:15:03

标签: sql sql-server-2008-r2

DECLARE @OrdersTemp TABLE
(
   OrderId UNIQUEIDENTIFIER
)

INSERT INTO @OrdersTemp
  SELECT ord.Id
  FROM Orders 

--all rows count
SELECT  
    @RowsCount = COUNT(DISTINCT ord.Id)
FROM   Orders 


--@RowsCount = 5. It's right!

--second table with paging
DECLARE @OrdersTempWithPaging TABLE
(
    OrderId UNIQUEIDENTIFIER
)

INSERT INTO @OrdersTempWithPaging
   SELECT OrderId
   FROM  (SELECT DISTINCT OrderId,
                 ROW_NUMBER() OVER (ORDER BY OrderId) AS RowNum
          FROM @OrdersTemp) AS alias
          WHERE 
              RowNum BETWEEN (@PageIndex - 1) * @PageSize + 1
                     AND @PageIndex * @PageSize

SELECT * FROM @OrdersTempWithPaging
--10 or more rows. It's wrong.

为什么@OrdersTempWithPaging会返回错误的行数?我该如何避免呢?

更新: 下面的语句返回25 = 5 * 5行(而不是5)

   INSERT  INTO @OrdersTempWithPaging
                SELECT    OrderId
                FROM    (
                          SELECT    OrderId,
                                    ROW_NUMBER() OVER (ORDER BY OrderId ) AS RowNum
                          FROM      @OrdersTemp ) AS alias
                --WHERE   RowNum BETWEEN ( @PageIndex - 1 ) * @PageSize + 1
                             --  AND     @PageIndex * @PageSize
  SELECT * FROM @OrdersTempWithPaging

3 个答案:

答案 0 :(得分:3)

这是因为你在select中的排序,

 SELECT    DISTINCT OrderId,
           ROW_NUMBER() OVER (ORDER BY OrderId ) AS RowNumber

您必须在列中进行排序,而不必在选择中使用DISTINCT。

 SELECT    OrderId,
           ROW_NUMBER() OVER (ORDER BY OrderId ) AS RowNumber

尝试一下,不用DISTINCT

答案 1 :(得分:2)

尝试此操作(撤消DISTINCT使用):

INSERT INTO @OrdersTempWithPaging
   SELECT DISTINCT OrderId
   FROM  (SELECT OrderId,
                 ROW_NUMBER() OVER (ORDER BY OrderId) AS RowNum
          FROM @OrdersTemp) AS alias
   WHERE 
       RowNum BETWEEN (@PageIndex - 1) * @PageSize + 1
              AND @PageIndex * @PageSize

如果您只需要不同的订单ID,则可以:

INSERT INTO @OrdersTemp
  SELECT DISTINCT ord.Id
  FROM Orders 

然后:

INSERT INTO @OrdersTempWithPaging
   SELECT OrderId
   FROM  (SELECT OrderId,
                 ROW_NUMBER() OVER (ORDER BY OrderId) AS RowNum
          FROM @OrdersTemp) AS alias
   WHERE 
       RowNum BETWEEN (@PageIndex - 1) * @PageSize + 1
              AND @PageIndex * @PageSize

答案 2 :(得分:0)

而不是

SELECT DISTINCT OrderId,
       ROW_NUMBER() OVER (ORDER BY OrderId) AS RowNum
FROM @OrdersTemp

使用

SELECT OrderId,
       ROW_NUMBER() OVER (ORDER BY OrderId) AS RowNum
FROM @OrdersTemp
GROUP BY OrderId

SELECT DISTINCTSELECT GROUP BY之间another difference这是一个有趣的案例,当选择列表包含排名函数时,它会显示出来。

在第一个查询中,输出包含来自OrderId的重复@OrdersTemp值,因为在应用 DISTINCT之前评估了排名函数。相反,第二个查询首先按OrderId对行进行分组(即首先有效地选择不同的OrderId值),然后应用排名。