Sql 基于自连接的更新

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

我试图做一个简单的计算,并根据匹配的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 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