2012-01-06 38 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