希望一次迁移20K行左右。已经离SQL超过10年并且在苦苦挣扎。
我可能会完全错误。需要使用Table1.Value2
中的最低值更新Table2.Value1
,除非已经Value2
。如果是后者,我需要插入一行,其值为Table1.Value1
。
Table1.Value1
是该行的每个ID的最低值。 Value2
需要是次低的。
当前表1:
ID1, 123, [empty]
ID4, 111, [empty]
当前表2:
ID1, 224
ID1, 331
ID4, 210
ID4, 551
表1 - 所需状态:
ID1, 123, 224
ID1, 331, [empty]
ID4, 111, 210
ID4, 551, [empty]
表2 - 所需状态:
[empty]
这是我尝试的内容,更新部分正常运行。插入从不起作用。我想我把自己编成了一个角落。
CREATE PROCEDURE dbo.Broken
AS
--DECLARE VARIABLES
DECLARE @ID INT,
@Value1 INT,
@Value2 INT,
@tmpValue INT
--DECLARE COUNTER
DECLARE @Counter INT
SET @Counter = 1
--DECLARE CURSOR FOR QUERY
DECLARE cTable1 CURSOR READ_ONLY FOR
SELECT ID,Value1, Value2
FROM Table1
OPEN cTable1
--FETCH VARIABLES
FETCH NEXT FROM cTable1 INTO @ID, @Value1, @Value2
--LOOP
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@Value2 = '' OR @Value2 is NULL)
BEGIN
--UPDATE Table1.Value2 with next lowest Table1.Value2 > Table1.Value1
SET @tmpValue = (SELECT MIN(Value1) FROM Table2 WHERE Value1 > @Value1 AND ID = @ID)
UPDATE Table1
SET Value2 = @tmpValue
WHERE ID = @ID
--DELETE AFFECTED ROW FROM Table2
DELETE FROM Table2
WHERE Value1 = @tmpValue AND ID = @ID;
END
ELSE
BEGIN
--INSERT ROW IN Table1 WITH ID, Value1 FROM Table2
SET @ID = (SELECT MIN(ID) FROM Table2)
SET @tmpValue = (SELECT MIN(Value1) FROM Table2 WHERE ID = @ID)
INSERT INTO Table1(ID, Value1, Value2)
VALUES (@ID, @tmpValue, '')
DELETE FROM Table2
WHERE ID = @ID
END
--FETCH NEXT VARIABLES
FETCH NEXT FROM cTable1 INTO @ID, @Value1, @Value2
END
--CLOSE THE CURSOR TABLE
CLOSE cTable1
DEALLOCATE cTable1
大约有2万行,所以我希望存储过程可以完成所有操作。这是一次性的,所以我并不十分关注开销。
答案 0 :(得分:0)
像这样的更新所需的基本查询非常清楚:
INSERT INTO Table1 (ID, Value1, Value2)
SELECT ID,
Value1,
[Empty]
From Table2 t2
LEFT JOIN Table1 t1
ON t2.ID = t1.ID
AND t2.Value1 = t1.Value1
LEFT JOIN Table1 t1a
ON t2.ID = t1a.Id
AND t2.Value1 = t1a.Value2
WHERE t1.Id IS NULL
AND t1a.Id IS NULL
DELETE FROM Table2
然后我会像这样执行插入:
let result = days_in_month.map(
year => year.map(
(days) => new Array(days)
)
);
请注意,这符合您的要求,但可能不符合您的实际要求 - @JeroenMostert的评论涵盖了其中一些问题。
答案 1 :(得分:0)
以下查询似乎产生了您想要的输出:
=if(countif(A1:A5,5)>=1,sum(A1:A5)+9,sum(A1:A5)-3)
考虑到这一点,一个简单的declare @Table1 table (
Id varchar(30) not null,
Value1 int null,
Value2 int null
);
declare @Table2 table (
Id varchar(30) not null,
Value int null
);
insert into @Table1 (Id, Value1)
values
('ID1', 123),
('ID4', 111);
insert into @Table2 (Id, Value)
values
('ID1', 224),
('ID1', 331),
('ID4', 210),
('ID4', 551);
select t2.Id,
case
when t2.Value = min(t2.Value) over(partition by t1.Id) then t1.Value1
else t2.Value
end as [V1],
case
when t2.Value = min(t2.Value) over(partition by t1.Id) then t2.Value
end as [V2]
from @Table1 t1
left join @Table2 t2 on t1.Id = t2.Id
where t1.Value1 < t2.Value;
就可以解决问题:
MERGE
我可能会遇到一些边缘情况,但原则上这应该有用。
答案 2 :(得分:0)
试试这个
;With updateData as (
Select Id , Value1 , row_number() over ( partition by id order by value1 ) rowNumber from table2
)
Update table1 set value2 = t.value1 from updateData t where t.Id = table1.Id and t.rowNumber=1
;With insertData as(
Select Id , Value1 , row_number() over ( partition by id order by value1 ) rowNumber from table2
)
Insert into table1(id,value1)
Select t.id , t.value1 from insertData t
Where t.rowNumber>1