vol*_*one 1 sql t-sql sql-server sql-server-2012 sql-server-2017
我有一个名为的表dbo.RecycleProductID只有一个主键ProductID列和一Used列:
ProductID (pk, int) | Used (bit)
23 1
65 1
68 1
90 NULL
104 NULL
...
60983471 NULL
Run Code Online (Sandbox Code Playgroud)
上表中有大约6.5米的ProductID值,需要"回收"并分配给不同表格中的产品.一旦将a ProductID分配给产品,我必须更新Used列值1以指示它已被使用.ProductID序列中存在间隙,有些存在数千个(例如,它可以从1010跳到8055)并且此表中的行数多于接收dbo.Product表表.
该dbo.Product表(大约1.5米行)只是一个产品列表,但没有ProductID值.
ProductID (pk, int) | ProductName (varchar)
23 Toothpaste
65 Speakers
68 Galaxy S8
NULL Plate
NULL Monitor
NULL Carpet
.....
Run Code Online (Sandbox Code Playgroud)
我目前正在运行的while循环,以获得ProductID从价值观dbo.RecycleProductID到dbo.Product表:
DECLARE @Max int = (select max(ProductID) from [dbo].[RecycleProductID]);
DECLARE @Min int = (select min(ProductID) from [dbo].[RecycleProductID]);
while @Min <= @Max
begin
UPDATE TOP (1)
[dbo].[Product]
SET ProductID = (SELECT TOP 1 ProductID FROM [dbo].[RecycleProductID] b1 WHERE b1.Used IS NULL ORDER BY ProductID ASC)
OUTPUT INSERTED.ProductID INTO dbo.UsedProductID
WHERE
ProductID is null;
UPDATE
rp1
SET
rp1.Used = 1
FROM
[dbo].[RecycleProductID] rp1
INNER JOIN
dbo.UsedProductID ub1 ON
ub1.ProductID = rp1.ProductID
set @Min = @Min+1
end;
Run Code Online (Sandbox Code Playgroud)
由于这基本上是一个游标,它需要永远.它已经运行了将近两天,只更新了大约326515行.有更快的方法吗?
试试这个查询:
with t1 as (
select
ProducID, row_number() over (order by ProducID) rn
from
RecycleProductID
where
used is null
)
, t2 as (
select
ProducID, row_number() over (order by ProducID) rn
from
Product
where
ProductID is null
)
update t2
set t2.ProducID = t1.ProducID
from
t2
join t1 on t2.rn = t1.rn
Run Code Online (Sandbox Code Playgroud)
编辑:此查询将更新RecycleProductID,可以单独执行
update RecycleProductID
set used = 1
where ProducID in (select ProductID from Product)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
197 次 |
| 最近记录: |