Sql 基于自连接的更新
我试图做一个简单的计算,并根据匹配的ID和ASOFDATE更新一个字段。这是我的剧本Sql 基于自连接的更新,sql,sql-server,azure-sqldw,Sql,Sql Server,Azure Sqldw,我试图做一个简单的计算,并根据匹配的ID和ASOFDATE更新一个字段。这是我的剧本 UPDATE A SET A.Vol30Days = (SELECT STDEV(PX_BID) OVER (ORDER BY ID, AsOfDate ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) FROM Prices) FROM Prices A INNER JOIN Prices B ON A.ID = B.ID AND
UPDATE A
SET A.Vol30Days =
(SELECT STDEV(PX_BID) OVER (ORDER BY ID, AsOfDate ROWS BETWEEN 30 PRECEDING AND CURRENT ROW)
FROM Prices)
FROM Prices A
INNER JOIN Prices B
ON A.ID = B.ID
AND A.AsOfDate = B.AsOfDate
子查询工作正常,逻辑看起来正常,但SQL Server抛出错误,UPDATE和DELETE语句中的FROM子句不能包含子查询源或联接。尝试使用子查询。我认为这是一个等价的逻辑:
UPDATE Prices
SET Vol30Days = (SELECT STDEV(PX_BID)
FROM (SELECT TOP (31) p2.*
FROM Prices p2
WHERE p2.ID <= prices.ID
) p2
);
尝试使用可更新的CTE:
WITH cte AS (
SELECT Vol30Days AS VolOrig,
STDEV(PX_BID) OVER (ORDER BY ID, AsOfDate ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) AS VolNew
FROM Prices
)
UPDATE cte
SET VolOrig = VolNew;
但考虑到新数据只是来自同一个表的派生数量,您可能希望避免更新,因为可能需要在表的数据更改时重新进行更新。相反,考虑创建一个视图。
使用中间存储,如表变量。
DECLARE @BIDS TABLE (ID integer, BIDS numeric(18,2))
INSERT INTO @BIDS (ID, BIDS)
SELECT A.ID, (SELECT STDEV(PX_BID) OVER (ORDER BY ID, AsOfDate ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) FROM Prices)
FROM Prices A
INNER JOIN Prices B ON A.ID = B.ID AND A.AsOfDate = B.AsOfDate
UPDATE A SET Vol30Days = B.BIDS
FROM Prices A
INNER JOIN @BIDS B ON B.ID = A.ID
或者,您可以使用时态表:
SELECT A.ID, (SELECT STDEV(PX_BID) OVER (ORDER BY ID, AsOfDate ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) FROM Prices) AS BIDS
INTO #BIDS
FROM Prices A
INNER JOIN Prices B ON A.ID = B.ID AND A.AsOfDate = B.AsOfDate
UPDATE A SET Vol30Days = B.BIDS
FROM Prices A
INNER JOIN #BIDS B ON B.ID = A.ID
DROP TABLE #BIDS
以下是推荐方法的文档: 使用JOIN子句的结果创建一个临时表 写入引用瞬态表的更新
请注意,带有连接的FROM子句(您最初的策略)目前处于私人预览中,不久将转到公共预览。谢谢。我刚刚试过,结果是:第1行第15列的解析错误:“TABLE”附近的语法不正确。@ASH应该可以。您确定正在使用SQL Server吗?。什么版本?@ASH我使用临时表添加了一个替代方案我使用的是Azure数据仓库。它似乎非常非常类似于SQL Server,但随着我对它的了解越来越深入,我发现了一些差异。谢谢Tim,但我的SQL Server版本不支持CTEs。@然后我郑重建议您升级您的SQL Server版本。谢谢Gordon!我只是尝试了一下,结果发现:多部分标识符A.Vol30Days无法绑定。我可以用中间的桌子来做这件事,但我一直在寻找更优雅、更容易维护的东西,就像蒂姆提到的。@ASH。你在上一个问题上有这个。SQL Server支持FROM子句中的联接。您需要更具体地了解您正在使用的数据库。谢谢Ron。谢谢大家。我现在已经准备好了!!
UPDATE A
SET A.Vol30Days = B.Vol30Days
FROM Prices A
INNER JOIN (
select t1.ID,
t1.AsOfDate,
STDEV(PX_BID) OVER (ORDER BY ID, AsOfDate ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) as Vol30Days
from Prices t1
) B
ON A.ID = B.ID
AND A.AsOfDate = B.AsOfDate