选择带行号的范围

时间:2016-02-24 12:07:10

标签: sql sql-server sql-server-2008

enter image description here

我需要SQL Server 2008表中的数据,其序列号(行号)的顺序相反(desc)。

我的表名是ProductDetails

我使用此查询

WITH Sum_Ctl (TOt) as 
(
    select count(*)+1 
    from ProductDetails 
    where ProductDetails.UserId = 38 
)
SELECT 
    Tot - ROW_NUMBER() OVER (ORDER BY PrdID asc) AS SNO,
    * 
FROM
    ProductDetails, Sum_Ctl 
WHERE
    UserId = 38 

用户38的表中存在2192行数据。我使用上面的查询

得到它
SNO  column 2192  2191  2190  .... to  1

问题:我需要20行数据,即仅2020到2000

我在查询中尝试了and SNO between 2020 and 2000,但得到了

  

无效的列名称'SNO'。

然后我试了

where 
    UserId = 38  
    and Tot - ROW_NUMBER() OVER (ORDER BY PrdID asc) between 2020 and 2000

但是

  

窗口函数只能出现在SELECT或ORDER BY子句中。

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:2)

这里有问题是你不能在where子句中使用窗口函数。这是logical processing order的结果。简而言之,行号是在处理完所有其他内容后生成的,包括where中可能包含的所有过滤器。

您可以使用子查询或CTE解决此限制。在此示例中,ROW_NUMBER在子查询中计算。这反过来又被主查询过滤。

示例

SELECT
    *
FROM
    (
        -- SNIO will be available to outer WHERE.
        SELECT
            ROW_NUMBER() OVER (ORDER BY PrdID ASC) AS sno,
            *
        FROM
            ProductDetails 
        WHERE
            ProductDetails.UserId = 38 
    ) AS sq
WHERE
    sno BETWEEN 2000 AND 2020
;

这是有效的,因为在将结果传递给外部查询之前,子查询是完整处理的。