SQL ORDER BY在条件之间指定顺序

时间:2015-05-07 13:57:04

标签: sql tsql

这是我的分页查询中选择8条记录的一部分:

 SELECT * FROM #Results  
        WHERE RowNumber BETWEEN(@PageIndex -1) * @PageSize + 1 AND(((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1 
 ORDER BY ad_type ASC,NEWID()

但是首先选择8条记录,然后按顺序排序。

我想首先按所有记录排序,然后选择8个下一个记录,而不会在下一页提取中重复记录。

这是我的第一页结果:

这是第二页结果: enter image description here

在第二页中有一条ad_type 2的记录,它应该在第一页而不是第一页结果中的最后一条记录

这就是我的所有程序:

GO
    ALTER PROCEDURE [dbo].[GetAdPageWise]  
        @PageIndex INT = 1  
       ,@PageSize INT = 3  
       ,@PageCount INT OUTPUT  

       ,@state_id int=NULL
    AS  
    BEGIN  
          SET NOCOUNT ON;  

SELECT  Id,ROW_NUMBER() OVER  
            (  
                  ORDER BY Id   
            )AS RowNumber 
      ,ad_title
      ,ad_brief  
      ,ad_pic
      ,ad_type    
INTO #Results
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY a.ID ORDER BY a.ID) AS rn, a.Id
      ,a.ad_title
      ,a.ad_brief  
      ,a.ad_pic
      ,a.ad_type    
    FROM [tbl_ads] a LEFT JOIN tbl_inf_adstate b ON a.Id=b.ad_id 
    WHERE (b.state_id=@state_id OR @state_id IS NULL) 
    AND a.ad_is_accept=1 
    AND a.ad_is_show=1 
    AND a.ad_is_slide=0 
)x
WHERE rn = 1


          DECLARE @RecordCount INT  
        SELECT @RecordCount = COUNT(*) FROM #Results  

          SET @PageCount = CEILING(CAST(@RecordCount AS DECIMAL(10, 2)) / CAST(@PageSize AS DECIMAL(10, 2)))  
        PRINT       @PageCount  

        SELECT * FROM #Results  
        WHERE RowNumber BETWEEN(@PageIndex -1) * @PageSize + 1 AND(((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1  ORDER BY ad_type ASC,NEWID()

        DROP TABLE #Results  
    END

我该怎么做?

2 个答案:

答案 0 :(得分:1)

听起来您想要同时展示特定广告类型的所有广告,因此您应首先按此排序。我根据显示的结果假设这个,没有"重复"但第一组是ad_id介于(1,45)之间,第二组是(46,58)。

要做到这一点,只需更改以下行(不需要PARTITION BY,因为我们只想创建一个从1到n的行号列表):

SELECT ROW_NUMBER() OVER (PARTITION BY a.ID ORDER BY a.ID) AS rn, a.Id

为:

SELECT ROW_NUMBER() OVER (ORDER BY a.ad_type, a.ID) AS rn, a.Id

但我确实在查询中看到了一些其他问题:

  1. 根据上面介绍的解决方案,它假定您下方的数据不会发生变化。假设只添加了行(且ad_id总是在增加)以前不是很大的问题,但现在我们先按ad_type排序,然后ad_id,可能是一个问题,应该在必要时进行说明。
  2. 为确保您的联接逻辑中没有错误,您应该在tbl_inf_adstate.ad_id上放置一个唯一约束,否则您需要更改联接,因为它会复制来自{{1}的行在你的结果中。
  3. 如果您使用的是SQL Server 2012或更高版本,则可能需要take a look at the new paging functionality it offers.

答案 1 :(得分:1)

    SELECT a.Id
          ,a.ad_title
          ,a.ad_brief  
          ,a.ad_pic
          ,a.ad_type    
     FROM [tbl_ads] a 
     LEFT JOIN tbl_inf_adstate b 
       ON a.Id = b.ad_id 
      AND a.ad_is_accept=1 
      AND a.ad_is_show=1 
      AND a.ad_is_slide=0
    WHERE b.state_id = @state_id 
       OR @state_id IS NULL             
    order by a.ad_type, a.Id 
   OFFSET (@PageIndex -1) * @PageSize ROWS 
    FETCH NEXT @PageSize ROWS ONLY;

ORDER BY Clause (Transact-SQL)