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ステートメントを配置すると、これは正しく表示されますが、SELECTステートメントを削除してSET部分で計算を行うと、機能しません。最終的に、5 月 18 日の一致が見つからなかった null の変更の値になります。

編集:LEFT JOINまたはLEFT OUTER JOINが必要かどうかわからないことを追加する必要があります。tab1 からすべての行を返したいのですが、それが tab2 に存在しない場合、変更値は、tab2.Value - tab1.Value ではなく、-tab1.Value にする必要があります。

4

1 に答える 1

0

DB2 では、メインの table-reference 句に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 番目の行を更新しようとしている場合、または存在しない場合は挿入しようとしている場合は、2 つのステートメント (またはおそらく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 に答える