Как объединить две записи и суммировать столбец тоже в SQL Server - PullRequest
0 голосов
/ 10 ноября 2019

Есть простая таблица с двумя столбцами. Col1 похож на идентификатор.

Я хочу суммировать количество строк с одинаковым значением Col1. И ОБНОВЛЕНИЕ текущая таблица.

Текущая таблица:

Col1 | Quantity
-----+----------
12   | 3
15   | 7
12   | 2

Мне нужна таблица ОБНОВЛЕННАЯ , чтобы СУММИТЬ количество двух строк сCol1 = 12 (например, WHERE Col1 = 12 ...) и объединить их в одну строку:

Col1 | Quantity
-----+----------
12   | 5
15   | 7

Как это возможно в запросе SQL Server?

Обратите внимание, чтоМне нужно обновить таблицу. Не просто выделять строки.

Ответы [ 2 ]

2 голосов
/ 10 ноября 2019

использование sum() агрегация с group by

with cte as 
(
select col1,quantity,row_number() over(partition by col1 order by quantity) as rn
from tablename
)

    update a set a.quantity=b.qty
    from cte a 
    inner join
    (select col1, sum(quantity) as qty
        from tablename
        group by col1
    )b on a.col1=b.col1 where rn=1

delete a from tablename a
join
(
select col1,quantity,row_number() over(partition by col1 order by quantity) as rn
    from tablename
)b on a.col1=b.col1 and rn>2
1 голос
/ 10 ноября 2019

Для этого можно использовать оператор MERGE.
Как и в случае с оператором UPDATE, его можно комбинировать с выражением Common-Table-Expression.
И в CTE могут использоваться оконные функции.

;WITH CTE AS
(
  SELECT *,
   ROW_NUMBER() OVER (partition by Col1 order by Quantity) as rn,
   SUM(Quantity) OVER (partition by Col1) as TotalQuantity,
   COUNT(*) OVER (partition by Col1) as Cnt
  FROM TestTable
)
MERGE (SELECT * FROM CTE WHERE cnt > 1) target
USING (SELECT * FROM CTE WHERE cnt > 1 AND rn = 1) src
ON (src.Col1 = target.Col1 AND src.rn = target.rn)
WHEN NOT MATCHED BY SOURCE 
    THEN DELETE
WHEN MATCHED
    THEN UPDATE SET target.Quantity = source.TotalQuantity;

Тест на rexrester здесь

Однако такое утверждение будет обновлять все записи таблицы при каждом повторном запуске. Даже когда дубли уже были удалены.
Но с несколькими настройками это станет запросом MERGE, который не обновляет те, у которых нет ошибок.

;WITH CTE AS
(
    SELECT *
    FROM
    (
        SELECT Col1, Quantity,
        ROW_NUMBER() OVER (partition by Col1 order by Quantity DESC) as rn,
        COUNT(*) OVER (partition by Col1) as cnt,
        SUM(Quantity) OVER (partition by Col1) as TotalQuantity
        FROM TestTable
    ) q
    WHERE cnt > 1
)
MERGE CTE t
USING (SELECT * FROM CTE WHERE rn = 1) src
ON (src.Col1 = t.Col1 AND src.rn = t.rn)
WHEN NOT MATCHED BY SOURCE
    THEN DELETE
WHEN MATCHED
    THEN UPDATE SET t.Quantity = src.TotalQuantity;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...