2012-01-06 41 views
2

我有兩個表TableA的和表B如下:如何使用Group By子句合併兩個sql服務器表?

表A:

 ItemID   Qty   Rate 
    --------  -----   -------- 
     1    10   100.00 
     2    20   150.00 

表B:

 ItemID   Qty   Rate 
    --------  -----   ------- 
     1    5   150.00 
     3    10   200.00 
     3    20   400.00 

現在我想要合併這兩個表。我期望的結果需要如下:

結果表A:

 ItemID   Qty   Rate 
    --------   -----   ------- 
     1    15   150.00 
     2    20   150.00 
     3    30   400.00 

我試過以下插入Select語句,但它沒有給出期望的結果。

INSERT INTO TableA 
(
    ItemID, 
    Qty, 
    Rate    
) 
SELECT 
    ItemID, 
    SUM(Qty), 
    MAX(Rate) 
FROM 
    TableB 
GROUP BY 
    ItemID 

但它給出結果如下:

 ItemID   Qty   Rate 
    --------  -----   -------- 
     1    10   100.00 
     2    20   150.00 
     1    5   150.00 
     3    30   400.00 

如何實現我想要的結果?

我想是這樣的:

MERGE PUR_PODetail AS Target 
       USING (
        SELECT 
         @POID, 
         ItemID, 
         SUM(POQuantity), 
         MAX(UnitRate), 
         1, 
         CASE WHEN D1 = '' THEN NULL ELSE D1 END D1, 
         CASE WHEN D2 = '' THEN NULL ELSE D2 END D2, 
         CASE WHEN D3 = '' THEN NULL ELSE D3 END D3, 
         CASE WHEN RandomDimension = '' THEN NULL ELSE RandomDimension END RandomDimension, 
         0 
        FROM 
         @Detail 
        GROUP BY 
         ItemID, D1, D2, D3, RandomDimension 
        ) AS Source ON (Target.ItemID = Source.ItemID) AND 
        (ISNULL(Target.D1, -999) = ISNULL(Source.D1, -999)) AND 
        (ISNULL(Target.D2, -999) = ISNULL(Source.D2, -999)) AND 
        (ISNULL(Target.D3, -999) = ISNULL(Source.D3, -999)) AND 
        (ISNULL(Target.RandomDimension, -999) = ISNULL(Source.RandomDimension, -999)) 
       WHEN MATCHED 
        THEN UPDATE SET 
          Target.POQuantity = Target.POQuantity + Source.POQuantity, 
          Target.UnitRate = MAX(Source.UnitRate) 
       WHEN NOT MATCHED 
        INSERT 
         (
          POID, 
          ItemID, 
          POQuantity, 
          UnitRate, 
          ItemStatusID, 
          D1, 
          D2, 
          D3, 
          RandomDimension, 
          EDInclusive_f 
         ) 
        VALUES 
         (
          @POID, 
          Source.ItemID, 
          Source.POQuantity, 
          Source.UnitRate, 
          1, 
          CASE WHEN Source.D1 = '' THEN NULL ELSE Source.D1 END D1, 
          CASE WHEN Source.D2 = '' THEN NULL ELSE Source.D2 END D2, 
          CASE WHEN Source.D3 = '' THEN NULL ELSE Source.D3 END D3, 
          CASE WHEN Source.RandomDimension = '' THEN NULL ELSE Source.RandomDimension END RandomDimension, 
          0 
         ) 

但它提供了以下錯誤。 請更正錯誤。我不知道這裏會出現什麼問題。

Msg 102,Level 15,State 1,Procedure PUR_PurchaseOrder_IU,Line 936 'MERGE'附近語法不正確。 Msg 156,Level 15,State 1,Procedure PUR_PurchaseOrder_IU,Line 953 關鍵字'AS'附近的語法不正確。

但是當我刪除這些MERGE語句從我的存儲過程,它執行...

回答

3

你不能只使用INSERT聲明這一點,你根據目標表中已存在的ItemID,必須爲INSERTUPDATE

SQL Server 2005中

UPDATE @TableA 
SET  Qty = a.Qty + b.Qty 
     , Rate = CASE WHEN a.Rate < b.Rate 
         THEN b.Rate 
         ELSE a.Rate 
        END 
FROM @TableA a 
     INNER JOIN (
      SELECT ItemID 
        , Qty = SUM(Qty) 
        , Rate = MAX(Rate) 
      FROM @TableB 
      GROUP BY 
        ItemID 
     ) b ON a.ItemID = b.ItemID 

INSERT INTO @TableA 
SELECT ItemID, Qty, Rate 
FROM (SELECT ItemID 
        , Qty = SUM(Qty) 
        , Rate = MAX(Rate) 
      FROM @TableB b 
      WHERE NOT EXISTS (SELECT * FROM @TableA a WHERE a.ItemID = b.ItemID) 
      GROUP BY 
        ItemID 
     ) b 

SQL Server 2008提供了MERGE聲明這一點。

根據與源表的連接結果對目標表執行插入,更新或刪除操作。例如,您可以通過插入,更新或刪除 一個表中的行,基於另一個表中的差異同步兩個表。

SQL Server 2008的

MERGE @TableA AS Target 
USING (
    SELECT ItemID 
      , Qty = SUM(Qty) 
      , Rate = MAX(Rate) 
    FROM @TableB 
    GROUP BY 
      ItemID 
) AS source (ItemID, Qty, Rate) ON (target.ItemID = source.ItemID) 
WHEN MATCHED THEN 
    UPDATE SET target.Qty = target.Qty + source.Qty 
      , target.Rate = CASE WHEN target.Rate < source.Rate 
            THEN source.Rate 
            ELSE target.Rate 
          END 
WHEN NOT MATCHED THEN 
    INSERT (ItemID, Qty, Rate) 
    VALUES (source.ItemID, source.Qty, source.Rate); 
+0

+1好沒有聯盟 – 2012-01-06 07:21:47

+1

請注意,費率不是總結 - 而是取最大值。請更正答案 – 2012-01-06 07:35:48

+0

@OlegDok - 你說的對,thx。答案已更新。 – 2012-01-06 08:03:38

1

試試這個:

MERGE TableA T 
USING 
(
    SELECT ItemId, SUM(Qty) Qty, MAX(Rate) Rate 
    FROM 
    (
    SELECT ItemId, Qty, Rate from TableA 
    UNION ALL 
    SELECT ItemId, Qty, Rate from TableB 
) S 
ON T.ItemId = S.ItemId 
WHEN MATCHED THEN UPDATE SET 
    Qty = S.Qty, 
    Rate= S.Rate 
WHEN NOT MATCHED THEN 
    INSERT(ItemId, Qty, Rate) 
    VALUES(S.ItemId, S.Qty, S.Rate); 
+0

嗨,我編輯了我的問題。請看看它,以及我的合併聲明中的錯誤。 – thevan 2012-01-06 10:43:08

0

聲明@t表(項ID INT,INT數量,速率INT) INSERT INTO @t值(1,10,100),(2,20,150)

SELECT * FROM @t

聲明@ T1表(項ID INT,INT數量,速率INT) INSERT INTO @ T1值(1,5,150),(3,10,200),(3,20,400)

SELECT * FROM從@ T1 @ T1

插入到@t 選擇項ID,SUM(數量)數量,最大值(速率)速率,其中ITEMID沒有(從@t選擇項目ID) 組由項目ID

選擇* from @t