【问题标题】:SQL Server ROW_NUMBER() on SQL Server 2000?SQL Server 2000 上的 SQL Server ROW_NUMBER()?
【发布时间】:2011-05-04 03:55:48
【问题描述】:

我有一个查询,通过给它一个最小和最大限制,我可以从数据库表中获取记录。

是这样的:

  SELECT T1.CDUSUARIO, T1.DSALIAS, T1.DSNOMBRE_EMPRESA, T1.DSCARGO, T1.DSDIRECCION_CORREO, T1.CDUSUARIO_ADMINISTRADOR, T1.FEMODIFICACION 
    FROM (SELECT *, 
               ROW_NUMBER() OVER (ORDER BY CDUSUARIO) as row FROM TBL_USUARIOS ) as T1 
   WHERE row > @limiteInf 
     and row <= @limiteSup 
ORDER BY DSALIAS ASC;

现在,它在 SQL Server 2005 和 SQL Server 2008 上运行得非常好,但尝试在 SQL Server 2000 数据库上运行它并显示:

ROW_NUMBER 是未知的函数名或类似名称。

我能做什么??

【问题讨论】:

    标签: sql sql-server sql-server-2000


    【解决方案1】:
    • 有一个带有 SELF JOIN 解决方案 here 的 COUNT(*) 会严重扩展
    • 您可以加载一个带有 IDENTITY 列的临时表并回读,但不能保证它可以正常工作(找不到关于它的文章,几年前在 MS 研讨会上被告知)

    这两种解决方案都不支持 PARTITION BY

    我没有提到可能更糟糕的基于循环或 CURSOR 的解决方案

    20011 年 5 月 20 日编辑

    为什么 IDENTITY 不起作用的示例演示:
    Do Inserted Records Always Receive Contiguous Identity Values

    【讨论】:

    • +1:COUNT / self join 也更像是使用 RANK/DENSE_RANK,因为重复项将获得相同的值
    • “两种解决方案都不支持 PARTITION BY”。您可以在加载到临时表时进行 GROUP BY。然后添加 IDENTITY 以获取每个组的 ID。然后,您可以将该临时表加入到您的原始查询中。
    【解决方案2】:

    我知道这个帖子有点老了,但是对于其他寻找相同解决方案的人来说,我认为知道这个问题有一个很好的解决方案会很有用。

    请看原文链接here

    对于那些不想点击链接的人,我复制并粘贴了下面的代码。再次感谢original publisher

    下面是 SQL Server 2000 的 SQL,用于选择按单列分组的记录的最新版本。

    SELECT *
      FROM (
        SELECT *, (
          SELECT COUNT(*)
            FROM MyTable AS counter
          WHERE counter.PartitionByColumn = MyTable.PartitionByColumn
            AND  counter.OrderByColumn >= MyTable.OrderByColumn
          ) AS rowNumber
        FROM MyTable
      ) AS r1
      WHERE r1.rowNumber = 1
    

    SQL Server 2005 中的相同代码如下所示:

    SELECT * FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY PartitionByColumn 
        ORDER BY OrderByColumn DESC) AS rowNumber FROM MyTable) AS rw1 
      WHERE rw1.rowNumber = 1
    

    【讨论】:

      【解决方案3】:

      使用其他功能或升级您的数据库。 ROW_NUMBER 在 2000 版本的数据库中不存在。观点。你对此无能为力。

      【讨论】:

      • 这似乎不是很有帮助。他显然知道不是在 2000 年,错误信息告诉他这一点。
      • @nathan gonzalez:这确实是基本事实:没有优雅的替代品
      • 没错。你知道,因为你不喜欢真相而投反对票也无济于事。这是事实。该功能是在 2000 年以后推出的,因为它丢失了。没有相同的性能替代品。
      【解决方案4】:

      这是我解决问题的方法:

      declare @i int
      declare @t table (row int, stuff varchar(99))
      insert into @t
      select 0,stuff from mytable -- <= your query
      set @i=0
      update @t set row=@i, @i=@i+1
      select * from @t
      

      解释:

      1. 创建内存表
      2. 插入行号为 0 的数据(您的查询)
      3. 用一个int变量更新行号字段,该变量在下一条记录的同一更新中递增(实际上该变量是先递增然后更新,因此它将从1开始)
      4. 从内存表中“选择”结果。

      你可能会问,为什么我不在 select 语句中使用变量呢?这会更简单,但这是不允许的,只有在没有结果的情况下。可以在更新中进行。

      【讨论】:

      • 请解释一下你在那里做什么
      猜你喜欢
      • 2011-09-23
      • 1970-01-01
      • 2010-12-17
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 2013-01-25
      • 2013-03-25
      • 2014-05-03
      相关资源
      最近更新 更多