0

我有这个加入:

UPDATE Table_Name
SET Change = isnull(tab2.Value,0) - tab1.Value 
FROM 
    (SELECT Date,ID,ID,FileName,Value FROM Table_Name WHERE FileName = 'x' AND Date = '2012-05-17') tab1
LEFT OUTER JOIN 
    (SELECT Date,ID,TradeID,FileName,Value FROM Table_Name WHERE FileName = 'x' AND Date = '2012-05-18')  tab2 
ON tab1.FileName = tab2.FileName AND 
tab1.ID = tab2.ID  AND 
tab1.ID = tab2.ID

如您所见,它是一个左外连接。但是,当我有 5 月 17 日的数据而 5 月 18 日没有数据时,插入的值应该是 -17th.Value(因为一般计算是 18th.Value - 17th.Value 和 18th.Value 为零)。

如果我在插入部分(用于调试)下方放置一个选择语句,则显示正确,但是,当我删除 SELECT 语句并在 SET 部分中进行计算时,它不起作用。我最终得到了 Change of null 的值,其中找不到 5 月 18 日的匹配项。

编辑:我应该补充一点,我不确定我是否需要 LEFT JOIN 或 LEFT OUTER JOIN。我希望从 tab1 返回所有行,如果它在 tab2 中不存在,则更改值应该是 -tab1.Value,而不是 tab2.Value - tab1.Value。

4

1 回答 1

0

DB2 不允许UPDATEs(或DELETEs)在主表引用子句中包含任何连接,我认为这可以防止某些类型的问题。是的,我知道您使用的是 SQL Server,这就是您尝试这样做的原因——我只是倾向于在编写时考虑到 DB2 约束,仅此而已。

假设您想更新 17 日的行,我相信以下应该有效。否则,请指定您实际要更新的行。

UPDATE Table_Name 
SET change = -value + COALESCE((SELECT nxt.value
                                FROM Table_Name nxt
                                WHERE nxt.fileName = table_name.fileName
                                AND nxt.id = table_name.id
                                AND nxt.scenarioId = table_name.scenarioId
                                AND nxt.cobDate = '2012-05-18'), 0)
WHERE fileName = 'GBP.csv'
AND cobDate = '2012-05-17'

编辑: 更正了上述错误。

但是...从事物的声音来看,您可能正在尝试更新不存在的行;具体来说,“结果需要输入18号”。如果您正在尝试更新那些确实存在的第 18 行,或者如果它们不存在则插入它们,那么您将需要两个语句(或者可能是一个MERGE?除非我的版本中没有它们,所以我不能帮你):

UPDATE Table_Name
SET change = value - COALESCE((SELECT prev.value
                               FROM Table_Name prev
                               WHERE prev.fileName = table_name.fileName
                               AND prev.id = table_name.id
                               AND prev.scenarioId = table_name.scenarioId
                               AND prev.cobDate = '2012-05-17'), 0)
WHERE fileName = 'GBP.csv'
AND cobDate = '2012-05-18';

INSERT INTO Table_Name (id, scenarioId, fileName, cobDate, value, change) 
                        SELECT id, scenarioId, fileName, '2012-05-18', 0, -value
                        FROM Table_Name
                        WHERE fileName = 'GBP.csv'
                        AND cobDate = '2012-05-17'
                        AND NOT EXISTS (SELECT '1'
                                        FROM Table_Name nxt
                                        WHERE nxt.fileName = table_name.filename
                                        AND nxt.id = table_name.id
                                        AND nxt.scenarioId = table_name.scenarioId
                                        AND nxt.cobDate = '2012-05-18');

必须按该顺序运行它们。
您还必须为 两个语句的组合运行锁定表,使用其他方法确保不修改包含相关数据的行(ed、d、d),或者能够判断哪些行没有被触及。INSERTUPDATEDELETE

如果这不是您想要的行为,请修改您的问题以更清楚地了解您要完成的工作。

于 2012-05-22T20:41:04.947 回答