0

How do i update a table in date order, I have a date field, TransactionDate, some column values are dependant on previous values, how do I itterate through a table to update in it date order.

I have tried a few things but keep coming across "The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified."

I have date ranges I want to re-process, changing older values means recalculating the newer values.

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'

When i insert the order by TransactionDate into the Join it sulks at me

3 Answers3

3

I would probably go with cursor if you need to iterate one row at a time:

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 

Is this what you're looking for?

nicdaniau
  • 3,356
  • 1
  • 13
  • 10
0

Try with 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' 
sallushan
  • 1,134
  • 8
  • 16
-1

In SQL server SQL2005+, you can use update table 'order by' by using 'with' and 'over', like the following:

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

reference

Community
  • 1
  • 1
Adel
  • 1,468
  • 15
  • 18