Tsql T-SQL:使用行号简化Select语句

Tsql T-SQL:使用行号简化Select语句,tsql,Tsql,我有以下select SQL,它执行基本select语句,尽管它确实包含计算列: Select * From ( Select *, ROW_NUMBER() OVER (ORDER BY CASE WHEN @sortBy = 0 THEN R.DateCreated End Desc,

我有以下select SQL,它执行基本select语句,尽管它确实包含计算列:

    Select *
    From
    (
      Select *,
             ROW_NUMBER() OVER
                              (ORDER BY
                                CASE WHEN @sortBy = 0 THEN R.DateCreated End Desc,
                                CASE WHEN @sortBy = 1 THEN R.DateCreated end Asc,
                                CASE WHEN @sortBy = 2 THEN TotalVotes END Desc,
                                CASE WHEN @sortBy = 2 THEN R.TotalFoundNotUseful END Desc
                              ) AS RowNumber 

      From
      (
        Select *, (TotalFoundUseful + TotalFoundNotUseful) As TotalVotes
      From Reviews
      Where (DealID = @dealID) And (TotalAbuses < 10) And (Deleted = 0)
    ) As R
  ) As Rev
  Where RowNumber BETWEEN @startRecord AND @endRecord

如果仔细观察,SELECT语句本身会执行3次。我不相信这是必要的。有没有办法把这个语句减少到两个select语句,或者甚至一个select语句。我实际上不需要返回行号。它仅用于选择特定范围内的行。

您可以通过将行数与原始的“对照检查选择”放在一起,使用两行来完成此操作。如果希望在诸如ROW_NUMBER之类的窗口函数上有WHERE子句,则不能转到其中一个

您确实需要编写两次TotalFoundUsage+TotalFoundNotUsage,但它只会被计算一次,这样就不会影响性能

我也不希望移动到两个对性能有任何影响,但您应该测试它

Select *
    From
    (
  Select *, (TotalFoundUseful + TotalFoundNotUseful) As TotalVotes,
          ROW_NUMBER() OVER
              (ORDER BY
            CASE WHEN @sortBy = 0 THEN DateCreated End Desc,
            CASE WHEN @sortBy = 1 THEN DateCreated end Asc,
            CASE WHEN @sortBy = 2 THEN TotalFoundUseful + TotalFoundNotUseful END Desc,
            CASE WHEN @sortBy = 2 THEN TotalFoundUseful END Desc
          ) AS RowNumber 
 From Reviews
     Where (DealID = @dealID) And (TotalAbuses < 10) And (Deleted = 0)

  ) As Rev
  Where RowNumber BETWEEN @startRecord AND @endRecord

选择没有执行三次。SQL Server将扩展派生表定义。Reviews表只命中一次,在最内层选择、筛选和计算总记录。下一个外部选择将顺序和行号添加到第一个,最外部的选择只返回数据页。对我来说,这似乎相当有效,因为任何分页策略在分页之前都需要知道筛选器中的总行数。我想我认为每次执行Select语句时,SQL Server都会迭代所有记录。因此,如果我在最里面的Select上有10条记录,中间的Select也会重复10次以执行排序。然后对最外层的Select再执行10次,这实际上会导致10x10x10=1000次迭代。@androiddev,您不应该将数据库视为对记录的迭代,除非您专门使用游标、while循环或相关子查询,否则它们在数据集而不是单个记录中工作。如果我有两条记录,其中TotalFoundUsage=100,但一条记录的TotalFoundNotUsage=5,另一条记录的TotalFoundNotUsage=3,则带5的记录首先出现,然后是带3的记录。我想要另一种方式。带3的那个应该放在第一位。我将上一个CASE语句修改为totalfoundnotusable END ASC,但这不起作用。因此当@Sortby=2时,它首先按totalvows排序,然后按totalfoundusable排序。您处理的问题数据的总票数是多少?