【问题标题】:ms sql row_number() function - won't let me use within the same statementms sql row_number() 函数 - 不允许我在同一语句中使用
【发布时间】:2012-03-25 03:12:19
【问题描述】:

我有如下sql语句:

$sql = "select siteid, row_number() OVER (ORDER BY siteid) as rownum FROM nwsite WHERE rownum >= 4";

“rownum”在我在查询之外使用名称时(例如在 foreach 循环中)有效,但是当将其用作 WHERE 子句时,它永远不会有效。

有什么想法吗?

谢谢

【问题讨论】:

  • 我的理解是解析函数是一个后处理步骤:一旦确定了结果集,就可以将结果集提供给解析函数来确定诸如行号、之前的行、什么行如下,等等。所以分析不能在 WHERE 子句中,因为它直到 where 子句被计算之后才被应用。因此,包裹在子查询中似乎是通常的方式。

标签: php sql sql-server where


【解决方案1】:

一种选择是

  • 将您的选择语句包装到子选择中
  • 在外部查询中使用 rownum 别名

SQL 语句

select *
from   (
         select siteid
                , row_number() OVER (ORDER BY siteid) as rownum 
         FROM   nwsite 
       ) q
where  rownum >= 4

【讨论】:

    【解决方案2】:

    因为在计算窗口函数 row_number 之前计算 where 子句,所以不能在 where 子句中包含该列。

    您可以像这样构造查询:

    select siteid, rownum from (select siteid, row_number() OVER (ORDER BY siteid) as rownum FROM nwsite) nw WHERE rownum >= 4

    在这种情况下,内部查询被完整计算,然后传递给可以对 rownum 列进行操作的外部查询。

    【讨论】:

    • 如果不进行子选择,having 子句是否也能正常工作?
    • @MarcB 不,您不能使用 HAVING 子句,因为 ms sql 很烂。在Mysql中完全没问题。
    • @JasonFuller - ROW_NUMBERHAVING 之后运行,因此允许在那里引用它也没有任何意义。 MySQL 还没有开始实现窗口函数。如果他们在这个问题上缺乏对 SQL 标准的遵守,那么他们将受到影响。
    【解决方案3】:

    试试这样:

    $sql = "select siteid, row_number() OVER (ORDER BY siteid) as rownum FROM nwsite WHERE row_number() >= 4";
    

    您不能在同一个 WHERE 子句的列部分中使用定义的别名。 WHERE 子句还没有这些信息。

    【讨论】:

      【解决方案4】:

      您还可以在CROSS APPLY 中定义RowNum,这样您就可以引用它。

      select siteid, 
             RowNum
      FROM nwsite 
      CROSS APPLY (SELECT row_number() OVER (ORDER BY siteid)) CxA(rownum)
      WHERE rownum >= 4
      
      【解决方案5】:

      使用公用表表达式:

      with Result (field1, field2...,rn)
      as
      (select field1, field2..., rn=row_number() over (partition by field1 order by field 2)
      from yourTable)
      select * from result where rn<=3 ; -- top 3 in each group
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-04
        • 2013-09-23
        • 1970-01-01
        • 1970-01-01
        • 2016-08-05
        • 2014-12-16
        • 1970-01-01
        • 2010-11-30
        相关资源
        最近更新 更多