按日期顺序更新表
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
【讨论】:
以上是关于按日期顺序更新表的主要内容,如果未能解决你的问题,请参考以下文章