求和然后删除一行 - SQL Server 2008 R2
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求和然后删除一行 - SQL Server 2008 R2相关的知识,希望对你有一定的参考价值。
我有这张桌子
CREATE TABLE #temp
(
Item VARCHAR(max),
Qty DECIMAL(18,2),
FixItem VARCHAR(max)
)
这是一些示例数据
INSERT INTO #temp (Item, Qty, FixItem)
VALUES ('ItemRandom-1', -- Item - varchar(max)
2, -- Qty - decimal
'ItemA' -- FixItem - varchar(max)
)
INSERT INTO #temp (Item, Qty, FixItem)
VALUES ('ItemRandom-2', -- Item - varchar(max)
5, -- Qty - decimal
'ItemA' -- FixItem - varchar(max)
)
INSERT INTO #temp (Item, Qty, FixItem)
VALUES ('ItemRandom-3', -- Item - varchar(max)
5, -- Qty - decimal
'ItemB' -- FixItem - varchar(max)
)
INSERT INTO #temp (Item, Qty, FixItem)
VALUES ('ItemRandom-4', -- Item - varchar(max)
5, -- Qty - decimal
'' -- FixItem - varchar(max)
)
INSERT INTO #temp (Item, Qty, FixItem)
VALUES ('ItemRandom-5', -- Item - varchar(max)
5, -- Qty - decimal
'' -- FixItem - varchar(max)
)
选择它时,结果如下:
Item Qty FixItem
--------------------------------
ItemRandom-1 2.00 ItemA
ItemRandom-2 5.00 ItemA
ItemRandom-3 5.00 ItemB
ItemRandom-4 5.00
ItemRandom-5 5.00
我想组合FixItem
所以我可以总结Qty
,然后删除ItemRandom-1
或ItemRandom-2
之间的一行
结果应该是这样的:
Item Qty FixItem
---------------------------------
ItemRandom-1 7.00 ItemA
ItemRandom-3 5.00 ItemB
ItemRandom-4 5.00
ItemRandom-5 5.00
我怎样才能做到这一点?提前致谢,对不起我的英语。
答案
这是一种方式。首先用每个FixItem
的总数量更新您的表格。然后删除额外的行。
update a
set a.Qty = b.Qty
from
#temp a
join (
select
FixItem, Qty = sum(Qty)
from
#temp
group by FixItem
) b on a.FixItem = b.FixItem
;with cte as (
select *, rn = row_number() over (partition by FixItem order by Item)
from #temp
)
delete from cte
where rn > 1
select * from #temp
产量
Item Qty FixItem
--------------------------------
ItemRandom-1 7.00 ItemA
ItemRandom-3 5.00 ItemB
编辑:
update a
set a.Qty = b.Qty
from
#temp a
join (
select
FixItem, Qty = sum(Qty)
from
#temp
where len(FixItem) > 0
group by FixItem
) b on a.FixItem = b.FixItem
;with cte as (
select *, rn = case when len(FixItem) > 0 then row_number() over (partition by FixItem order by Item) else 0 end
from #temp
)
delete from cte
where rn > 1
另一答案
这是实现结果的一种方法:
SELECT MIN(item) AS item,
SUM(qty) AS qty,
fixitem
FROM #temp
GROUP BY fixitem;
另一答案
我不知道你在寻找什么但是对于实例作为期望的结果看你需要GROUP BY
子句并使用min()
函数来获得第一个Item
,不需要删除该项目。
SELECT
MIN(Item) Item,
SUM(Qty),
FixItem
FROM #temp t
GROUP BY FixItem
对我来说删除将是不必要的操作,因为结果将显示qty 7
的总和,但实际将显示另一个而不是为ItemRandom-1汇总7
DELETE t FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY FixItem ORDER BY Item) Seq
FROM #temp
) t
WHERE Seq > 1
您可以使用窗口函数来实现结果
select Item,
SUM(Qty) OVER (ORDER BY FixItem ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) Qty,
FixItem
from #temp
另一答案
您可以使用select查询来实现此目的,无需删除记录。对于此选择查询,您还可以创建视图以便于访问。
根据要求,您可以在项目列中放置最小值或最大值。
select min(item) item, SUM(qty) qty, fixitem from #temp
where fixitem != '' group by fixitem
union all
select item, qty, fixitem from #temp
where fixitem = ''
另一答案
为什么不使用MERGE声明?
CREATE TABLE #temp(
Item VARCHAR(max),
Qty DECIMAL(18,2),
FixItem VARCHAR(max)
);
INSERT INTO #temp(Item, Qty, FixItem)
VALUES
('ItemRandom-1', 2, 'ItemA'),
('ItemRandom-2', 5, 'ItemA'),
('ItemRandom-3', 5, 'ItemB'),
('ItemRandom-4', 5, ''),
('ItemRandom-5', 5, '');
WITH
t AS (
SELECT *,
SUM(Qty)OVER(PARTITION BY FixItem) t,
ROW_NUMBER()OVER(PARTITION BY FixItem ORDER BY Item) n
FROM #temp
WHERE FixItem != ''
)
MERGE t USING (SELECT * FROM t WHERE n = 1) s
ON t.Item = s.Item AND t.FixItem = s.FixItem AND t.n = s.n
WHEN MATCHED THEN UPDATE SET t.Qty = s.t
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT $action, deleted.*;
SELECT * FROM #temp;
结果可以在rextester.com进行调查。
OUTPUT子句用于演示MERGE语句的功能。
以上是关于求和然后删除一行 - SQL Server 2008 R2的主要内容,如果未能解决你的问题,请参考以下文章