Sql Server - 根据主键更新多行(大量数据)

时间:2014-07-29 11:43:49

标签: sql sql-server-2012

挣扎于这个,这是一个非常冗长的描述,所以我可以解释得最好:

我有一个包含12列的表,1是一个带有identity_insert的主键,1是一个外键,另外10个是成本值,我创建了一个语句,将它们分为5个类别,如下所示:

select
(ProductID)ProjectID,
sum(Cost1)Catagory1,
sum(Cost2)Catagory2,
sum(Cost3 + Cost4 + Cost5 + Cost6 + Cost7) Catagory3,
sum(Cost 8 + Cost 9)Catagory4,
sum(Cost10)Catagory5
from ProductTable group by ProductID

我改变了数据的名称,使其更通用,顺便说一下,它们实际上并没有被称为Cost1等;)

外键可以出现多次(ProductID)所以在上面的查询中,相关的字段是基于此一起计算的...现在我一直在尝试做的是把这个查询放到一个表中,我已经成功完成了,然后通过一个过程更新数据。我遇到的问题是表中的所有数据都被第1行覆盖,当有数千行时,这是一个问题。

我也尝试将上述查询放入视图中并得到相同的结果......任何建议都会很棒:)

update NewTable set
ProductID = (ProductView.ProductID ),
Catagory1 = (ProductView.Catagory1 ),
Catagory2 = (ProductView.Catagory2 ),
Catagory3 = (ProductView.Catagory3 ),
Catagory4 = (ProductView.Catagory4 ),
Catagory5 = (ProductView.Catagory5 )
from ProductView

我需要像上面那样的东西....但是没有用第1行覆盖所有东西哈哈;)

回答:Noman_1

create procedure NewProducts
insert into NewTable
select ProductID.ProductTable,
Catagory1.ProductView,
Catagory2.ProductView,
Catagory3.ProductView,
Catagory4.ProductView,
Catagory5.ProductView
from ProductView
inner join ProductTable on ProductView.ProductID = ProductTable.ProductID 
where not exists(select 1 from NewTable where ProductView.ProductID = NewTable.ProductID)

上面的过程找到了在视图中创建的新产品,过程查询检测到有一个产品不在NewTable中并通过过程插入

2 个答案:

答案 0 :(得分:2)

据我所知,由于您想要更新表中的所有产品,并且每个产品都使用产品本身的所有总和,您实际上需要逐行更新每一行,并作为连续性当你像下一个那样进行更新时,它是你唯一的主要方式

update newtable
set category1 = (select sum(cost1) from productTable where productTable.productId = newtable.ProductID),
category2 = (select sum(cost2) from productTable where productTable.productId = newtable.ProductID),
etc..

请记住,如果你有新产品,他们不会插入更新,你需要这样才能添加它们:

Insert into newtable
Select VALUES from productTable a where productId not exists(select 1 from newTable b where a.ProductId = b.ProductId);

第二种方式,因为你想要总是更新所有数据,就是简单地截断并在之后进行插入选择。

也许在Oracle上,你可能会使用MERGE,但我不知道它是否能真正改善任何东西。

我认为由于您声明的数据量,仅仅拥有一个视图是行不通的。

编辑,我从来不知道MERGE STATMENT实际上可以在SQL Server 2008及更高版本上使用,有了这个单一的声明你可以对所有内容进行更新/插入,但是我的效率是未知的,你可能想用它来测试它您的大量数据:

MERGE newtable AS TARGET
USING select ProductId, sum(cost1) cat1, sum(cost2) cat2 ... 
FROM productTable Group by ProductId AS SOURCE
ON TARGET.ProductId = SOURCE.ProductID
WHEN MATCHED 
THEN UPDATE SET TARGET.category1 = cat1, TARGET.category2 = cat2...
WHEN NOT MATCHED 
THEN INSERT (ProductId, category1, category2,...) 
VALUES (SOURCe.ProductId, SOURCE.cat1, SOURCE.cat2...);

有关合并的更多信息: http://msdn.microsoft.com/library/bb510625.aspx

最后的例子可能会让你对sintax有一个很好的概述

答案 1 :(得分:0)

您尚未提供任何加入条件。 SQL Server无法知道您是否要更新与productid匹配的行。

update NewTable set
ProductID = (ProductView.ProductID ),
Catagory1 = (ProductView.Catagory1 ),
Catagory2 = (ProductView.Catagory2 ),
Catagory3 = (ProductView.Catagory3 ),
Catagory4 = (ProductView.Catagory4 ),
Catagory5 = (ProductView.Catagory5 )
from NewTable
join ProductView pv on NewTable.productid = pv.productid

您不需要视图。刚过视图查询到我说ProductView的地方。当然,你可以使用视图。