如何使用Group By子句合并两个sql server表?

时间:2012-01-06 07:10:34

标签: sql sql-server sql-server-2005 group-by

我有两个表TableA和TableB如下:

表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

我尝试了以下Insert 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,936行 “MERGE”附近的语法不正确。 消息156,级别15,状态1,过程PUR_PurchaseOrder_IU,行953 关键字“AS”附近的语法不正确。

但是当我从我的存储过程中删除这些merge语句时,它正在执行...

3 个答案:

答案 0 :(得分:3)

您不能只使用INSERT语句,您必须INSERTUPDATE,具体取决于目标表中已存在的ItemID。

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);

答案 1 :(得分: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);

答案 2 :(得分:0)

声明@t表(ItemID int,Qty int,Rate int) 插入@t值(1,10,100),(2,20,150)

从@t

中选择*

声明@t1表(ItemID int,Qty int,Rate int) 插入@ t1值(1,5,150),(3,10,200),(3,20,400)

从@ t1

中选择*

插入@t 从@ t1中选择ItemID,sum(Qty)Qty,max(Rate)Rate,其中ItemID不在(从@t中选择ItemID) 按ItemID分组

从@t

中选择*