【问题标题】:ms sql 2000 row_number codems sql 2000 row_number 代码
【发布时间】:2014-05-29 12:42:21
【问题描述】:

我尝试使用 row_number 函数为 MS SQL 2000 编写 SQL 语法... SQL 2000 不支持 OVER 的 row_number,所以我尝试了这段代码....

当我写这篇文章时:

    SELECT P1.*,
            (SELECT COUNT(*) FROM Persons P2 
                   WHERE P2.Value<= P1.Value ) AS NewValue
             FROM Persons P1
    WHERE ...

一切正常,我得到一个带有 row_numbers 的新列 'NewValue'...

但是,当我尝试用这个新列更新表中的一列时,我总是得到一个错误:

“派生表不可更新,因为派生表的列是派生的或不变的……”????怎么了?

这是一个完整的语法:

    UPDATE t
    SET    t.Value= t.NewValue
    FROM   (SELECT P1.*,
            (SELECT COUNT(*) FROM Persons P2 
                WHERE P2.Value<= P1.Value) AS NewValue
             FROM Persons P1) t
    WHERE     ....

'Value' 是表中的一列,我无法使用 'NewValue' 列中的值进行更新...

非常感谢!!! :)

【问题讨论】:

    标签: sql sql-server-2000 row-number


    【解决方案1】:

    你应该改变并直接在SET子句中作为子查询进行计数:

    UPDATE P1
    SET    Value= (SELECT COUNT(*) FROM Persons P2 
                WHERE P2.Value<= P1.Value)
    FROM   Persons P1
    WHERE     ....
    

    【讨论】:

      【解决方案2】:

      这意味着 SQL Server 无法确定如何更新实际数据。此错误可能出现在两种情况下:

      1. 您正在尝试更新常量字段。示例:

        update T
        set Title = N'New title goes here'
        from
            (select 'Old title' as Title) as T
        
      2. 您正在尝试更新派生值。示例:

        update T
        set MaxPrice = 512
        from
            (select max(Price) as MaxPrice) as T
        

      为避免此问题,您可以考虑向表中添加主键,或基于唯一索引进行更新。在少数情况下,您需要一个没有主键或唯一索引的表。如果您完全确定任何主键或唯一索引都会损害架构,您可能需要模拟row_number,例如like this

      select 
          RowNumber = identity(int, 1, 1),
          c.LastName,
          c.FirstName
      into #Customer_RowID
      from SalesLT.Customer c
      order by c.LastName asc
      

      鉴于缺乏唯一性约束,请确保您在事务中执行选择更新以避免更新不同的行。

      【讨论】:

        【解决方案3】:

        我不知道为什么这种语法在 SQL Server 2000 中不起作用。我很确定这种语法在更新版本的 SQL Server 中也能起作用。

        也许您应该考虑升级到受支持的产品。

        此版本可能有效:

           UPDATE Persons
             SET t.Value =  (SELECT COUNT(*) FROM Persons P2 WHERE P2.Value <= Persons.Value)
             WHERE     ....;
        

        【讨论】:

        • SET 中分配的左侧不允许使用表别名(现在别名应该已经更改,因为您已经消除了较大的子查询)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-04
        • 2013-09-23
        • 2011-09-23
        • 1970-01-01
        • 2010-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多