按日期顺序更新表

Posted

技术标签:

【中文标题】按日期顺序更新表【英文标题】:Updating a table in date order 【发布时间】:2014-06-03 11:16:47 【问题描述】:

如何格,我有一个日期字段 TransactionDate,某些列值依赖于以前的值,我如何遍历表格以按日期顺序更新。

我尝试了一些方法,但一直遇到“ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP 或 FOR XML。”

我有想要重新处理的日期范围,更改旧值意味着重新计算新值。

UPDATE M
SET M.AvgGain = CASE WHEN M.Price > Previous.Price THEN ( ISNULL( Previous.AvgGain * 13.0, 0 ) + ( M.Price - Previous.Price )) / 14.0 ELSE  ( ISNULL( Previous.AvgGain * 13.0, 0 ) / 14.0 )END
FROM SalesData M
JOIN SalesData AS Previous ON ( SELECT TOP 1 PK FROM SalesData WHERE AbbrevID = M.AbbrevID AND TransactionDate < M.TransactionDate ORDER BY TransactionDate DESC) = Previous.PK
WHERE M.AbbrevID IN ( SELECT PK FROM SalesData  WHERE AbbrevID = ( SELECT PK FROM SalesPeople WHERE Abbreviation = 'Fred') ) AND TransactionDate BETWEEN '1996-02-23' and '1996-05-08'

当我将 TransactionDate 的订单插入到 Join 中时,我很生气

【问题讨论】:

请编辑您的问题以提供示例数据和您想要做什么。否则,你的问题太模糊了。 你能显示你写的查询吗? 查询中的括号没有正确关闭,最后一个AND是用于最外层查询还是内层查询? 最后一个And是在正确的地方,但你是对的,最后一个额外的括号,我会修改。 【参考方案1】:

如果您需要一次迭代一行,我可能会使用 cursor:

DECLARE @c_mem INT -- for example some numbeer of day, ie the calcuation you need to make from previous rows
SET @c_mem = 0 -- some initial value

DECLARE db_cursor CURSOR FOR  
SELECT [your_table_UID_field]
FROM [your_table_name]
ORDER BY TransactionDate

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @c_uid  

WHILE @@FETCH_STATUS = 0  
BEGIN  
       SET @c_mem=[some calculation based on c_mem itself and the current transac date]
       UPDATE [your_table_name]
       SET TransactionDate=[some calculation based on @c_mem, eg transac date + c_mem days]
       WHERE [your_table_UID_field]=@c_uid;

       FETCH NEXT FROM db_cursor INTO @c_uid  
END  

CLOSE db_cursor  
DEALLOCATE db_cursor 

这是你要找的吗?

【讨论】:

【参考方案2】:

试试CROSS APPLY

UPDATE    M
    SET M.AvgGain = CASE WHEN M.Price > Previous.Price THEN 
                        ( ISNULL( Previous.AvgGain * 13.0, 0 ) + ( M.Price - Previous.Price )) / 14.0 
                    ELSE  
                        ( ISNULL( Previous.AvgGain * 13.0, 0 ) / 14.0 )
                    END
FROM    SalesData AS M
        CROSS APPLY (
            SELECT    TOP 1 AvgGain, Price
            FROM      SalesData
            WHERE     AbbrevID = M.AbbrevID AND TransactionDate < M.TransactionDate 
            ORDER BY TransactionDate DESC
        ) AS Previous
WHERE    M.AbbrevID IN ( 
                    SELECT     PK 
                    FROM     SalesData  
                    WHERE     AbbrevID = ( SELECT PK FROM SalesPeople WHERE Abbreviation = 'Fred')      
                )
        AND TransactionDate BETWEEN '1996-02-23' and '1996-05-08' 

【讨论】:

【参考方案3】:

在 SQL server SQL2005+ 中,您可以通过使用 'with' 和 'over' 来使用更新表 'order by',如下所示:

With XYX As
(
  SELECT id,Field2, ROW_NUMBER() 
           OVER (ORDER BY YourDateField DESC) AS RN
  FROM YourTable
)
UPDATE XYX SET Field2=RN

reference

【讨论】:

以上是关于按日期顺序更新表的主要内容,如果未能解决你的问题,请参考以下文章

MySQL PHP插入新行,其中rowNum列值始终按日期和时间按时间顺序排列

SQL Server 编程 - 按给定天数更新所有日期

SQL多表联合查询按日期排序

SQL 动态数据透视表列顺序

怎样按日期排序LIST集合

获取按月顺序显示的特定日期之间的所有订单