Как объединить две таблицы SQL Server с помощью предложения Group By? - PullRequest
2 голосов
/ 06 января 2012

У меня есть две таблицы TableA и TableB следующим образом:

TableA:

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

TableB:

     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
                        )

Но это даетследующая ошибка.Пожалуйста, исправьте ошибку.Я не знаю, что здесь будет не так.

Сообщение 102, Уровень 15, Состояние 1, Процедура PUR_PurchaseOrder_IU, Строка 936 Неверный синтаксис рядом с 'MERGE'.Сообщение 156, уровень 15, состояние 1, процедура PUR_PurchaseOrder_IU, строка 953 Неверный синтаксис рядом с ключевым словом "AS".

Но когда я удаляю эти операторы слияния из моей хранимой процедуры, он выполняет ...

Ответы [ 3 ]

3 голосов
/ 06 января 2012

Вы не можете просто использовать для этого оператор INSERT, вам нужно либо INSERT, либо UPDATE в зависимости от того, какой 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 голос
/ 06 января 2012

Попробуйте это:

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 голосов
/ 23 апреля 2013

объявить таблицу @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 Выбрать ItemID, сумма (Кол-во) Кол-во, макс. (Скорость) Оценить от @ t1, где ItemID не входит в (Выберите ItemID из @t) по ItemID

Выбрать * из @ t

...