2011-05-06 23 views
1
FOR v2 AS 
    c2 CURSOR FOR 
     SELECT he.MyPrimary, he.SomeCode, he.SomeName, pe.MyPrimary 
     FROM SomeTable he 
      INNER JOIN AnotherTable pe 
       ON (he.ColOne = pe.FooOne 
        AND he.ColTwo = pe.ColTwo 
        AND he.ColThree = pe.FooOne 
        AND he.SomeCode = pe.SomeCode) 
     WHERE he.relevancy = 1 AND he.ColThree = '2011-01-05' AND he.ColFive = 9 
DO 
    UPDATE AnotherTable SET match = he.MyPrimary, FooTwo = he.SomeCode, SomeName = he.SomeName WHERE MyPrimary = pe.MyPrimary; 

END FOR; 

我上面的代碼,我試圖做到這一點,而無需使用遊標,但我不知道該怎麼辦的UPDATE聲明與INNER JOIN。基本上,我想要做的就是連接兩個表SomeTableAnotherTable然後基於一些列的值從SomeTable,值複製到類似列AnotherTable。我正在使用DB2。優化這個UPDATE語句不使用遊標

編輯:我只是在尋找到這一點:INNER JOIN in UPDATE sql for DB2

它將使意義做這樣的事情,而不是:

UPDATE 
    SomeTable pe 
SET 
    match = (SELECT he.MyPrimary FROM SomeTable he WHERE he.ColOne = pe.FooOne 
          AND he.ColTwo = pe.ColTwo 
          AND he.ColThree = pe.FooOne 
          AND he.SomeCode = pe.SomeCode), 

    FooTwo = (SELECT he.SomeCode FROM SomeTable he WHERE he.ColOne = pe.FooOne 
          AND he.ColTwo = pe.ColTwo 
          AND he.ColThree = pe.FooOne 
          AND he.SomeCode = pe.SomeCode) 
WHERE 
    he.relevancy = 1 AND he.ColThree = '2011-01-05' AND he.ColFive = 9 

回答

1

由於你的鏈接所提到的,ISO/ANSI標準不允許在子查詢中使用Update語句之外的聯接。因此,你必須要麼做多的更新語句,或使每個列的子查詢。

Update AnotherTable 
Set match = (
       Select he.MyPrimary 
       From SomeTable he 
       Where he.ColOne = AnotherTable.FooOne 
        And he.ColTwo = AnotherTable.ColTwo 
        And he.ColThree = AnotherTable.FooOne 
        And he.SomeCode = AnotherTable.SomeCode 
        And he.relevancy = 1 
        And he.ColThree = '2011-01-05' 
        And he.ColFive = 9 
       ) 
    , FooTwo = (
       Select he.SomeCode 
       From SomeTable he 
       Where he.ColOne = AnotherTable.FooOne 
        And he.ColTwo = AnotherTable.ColTwo 
        And he.ColThree = AnotherTable.FooOne 
        And he.SomeCode = AnotherTable.SomeCode 
        And he.relevancy = 1 
        And he.ColThree = '2011-01-05' 
        And he.ColFive = 9 
       ) 
    , SomeName = (
        Select he.SomeName 
        From SomeTable he 
        Where he.ColOne = AnotherTable.FooOne 
         And he.ColTwo = AnotherTable.ColTwo 
         And he.ColThree = AnotherTable.FooOne 
         And he.SomeCode = AnotherTable.SomeCode 
         And he.relevancy = 1 
         And he.ColThree = '2011-01-05' 
         And he.ColFive = 9 
        ) 
Where Exists (
       Select 1 
       From SomeTable he 
       Where he.ColOne = AnotherTable.FooOne 
        And he.ColTwo = AnotherTable.ColTwo 
        And he.ColThree = AnotherTable.FooOne 
        And he.SomeCode = AnotherTable.SomeCode 
        And he.relevancy = 1 
        And he.ColThree = '2011-01-05' 
        And he.ColFive = 9 
       ) 
+0

我真的只是關心性能。這會比使用遊標的原始遊戲快嗎? – Connection 2011-05-06 22:27:00

+0

@SQLizer - 你將不得不測試它知道。查詢引擎可能會明智地意識到你正在試圖執行三個相同的子查詢。如果不是,另一個解決方案是三個更新查詢。這兩種解決方案之一應該比光標更快。 – Thomas 2011-05-06 22:51:31

+0

貌似是因爲事情的方式設置在這裏,光標實際上比其他兩種解決方案快(分鐘)。所以現在看來​​,改變它沒有意義。 – Connection 2011-05-06 23:59:19

0

有一個更好的方法來做到這一點;

UPDATE SomeTable pe SET (match, FooTwo, SomeName) = (SELECT he.MyPrimary, he.SomeCode, he.SomeName 
                FROM AnotherTable he 
                WHERE he.ColOne = pe.FooOne 
                AND he.ColTwo = pe.ColTwo 
                AND he.ColThree = pe.FooOne 
                AND he.SomeCode = pe.SomeCode) 
WHERE he.relevancy = 1 
AND he.ColThree = '2011-01-05' 
AND he.ColFive = 9 

這工作得很好,DB2的iSeries的版本。
如果你需要擔心NULL行,不要忘記你的存在子句:

AND EXISTS (SELECT '1' 
      FROM AnotherTable he 
      WHERE he.ColOne = pe.FooOne 
      AND he.ColTwo = pe.ColTwo 
      AND he.ColThree = pr.FooOne 
      AND he.SomeCode = pe.SomeCode) 

加入,現有的WHERE條款後,在主UPDATE聲明。