代码之家  ›  专栏  ›  技术社区  ›  Nick Veys

在where子句中使用排序函数派生列(SQL Server 2008)

  •  8
  • Nick Veys  · 技术社区  · 16 年前

    希望这对SQL忍者来说是微不足道的。。。正在尝试使以下查询正常工作:

    SELECT 
        ROW_NUMBER() OVER (ORDER BY Date_Time DESC) AS RowNumber, *
    FROM
        (SELECT 
             T.A_ID, T.User_Name, T.Date_Time, T.Value,
             U.ID, U.Name, U.Field1, U.Field2,
             COUNT(U.ID) OVER () AS TotalRows
         FROM 
            TeeTable as T 
        INNER JOIN 
            YouTable AS U ON T.U_ID = U.ID
        WHERE 
            T.Value BETWEEN 222 AND 225) Filtered
    WHERE 
        RowNumber BETWEEN 1 AND 5
    

    这些值在某种程度上是为了给出一个特定的示例,但查询的精神完全保留了下来。我从该语句中得到的错误是:

    列名“RowNumber”无效。

    我也尝试过将其重新安排为CTE(过滤为…),但最终结果是一样的,看来这只是我已经在做的事情的一个糖分。

    思想?如何根据RowNumber派生列进行筛选?

    3 回复  |  直到 10 年前
        1
  •  18
  •   Remus Rusanu    16 年前

    您必须移动WHERE操作符 在上面 创建“行号”列的项目列表。使用派生表或CTE:

    SELECT * 
      FROM (
       SELECT *, ROW_NUMBER() OVER (...) as RowNumber
       FROM ...) As ...
     WHERE RowNumber = ...
    

    WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (...) as RowNumber
           FROM ...)
    SELECT * FROM cte 
    WHERE RowNumber = ...   
    
        2
  •  5
  •   RBarryYoung    16 年前

    窗口函数(最熟悉的是它的行号)在查询中很晚才填充,在WHERE子句之后。因此,您也必须嵌套它,以便在其上进行过滤:

    SELECT *
    FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY Date_Time DESC) AS RowNumber, *
        FROM
        ( SELECT T.A_ID, T.User_Name, T.Date_Time, T.Value,
                 U.ID, U.Name, U.Field1, U.Field2,
                 COUNT(U.ID) OVER () AS TotalRows
          FROM 
            TeeTable as T INNER JOIN YouTable AS U
            ON T.U_ID = U.ID
            WHERE T.Value BETWEEN 222 AND 225
        ) Numbered
    )  Filtered
    WHERE RowNumber BETWEEN 1 AND 5
    

    您也可以将它们放在CTE或视图中以获得相同的效果。

        3
  •  1
  •   Shashank Raj Chavan    11 年前

    查询的问题是由于逻辑处理顺序中的错误造成的。这是MSDN dev网络中指定的逻辑处理顺序。

    SELECT语句的逻辑处理顺序 以下步骤显示SELECT语句的逻辑处理顺序或绑定顺序。此顺序确定在一个步骤中定义的对象何时可用于后续步骤中的子句。例如,如果查询处理器可以绑定(访问)FROM子句中定义的表或视图,则所有后续步骤都可以使用这些对象及其列。相反,由于SELECT子句是步骤8,因此前面的子句不能引用该子句中定义的任何列别名或派生列。但是,它们可以由后续的子句(如ORDER by子句)引用。请注意,语句的实际物理执行由查询处理器决定,并且顺序可能与此列表不同。 从…起 参加 分组 有 挑选 订购人

    因此,在from部分的子查询中将ranking函数作为别名引入,然后您将能够在where部分的别名上设置条件。

    推荐文章