[英]Performance Issue in While Clause
好的,大家好
提前道歉。 不过,这个实际上很有趣。
我写了一个我昨天半自豪的SQL脚本,因为我觉得它很聪明。 事实证明它会因性能问题而受到破坏,因此我甚至无法测试它,因此它甚至可能不会做我想的叹息 。
最好用一个例子解释这个问题:
Heart | K | 2/1/2013 | 3/1/2013
Heart | K | 2/1/2013 | 3/1/2013
Heart | K | 1/1/2013 | 3/1/2013
Heart | K | 2/1/2013 | 4/1/2013
Spade | 4 | 2/1/2013 | 3/1/2013
Spade | 3 | 2/1/2013 | 3/1/2013
Club | 4 | 2/1/2013 | 3/1/2013
使用此表,我需要:1。从第一个开始,如果列A中的值匹配,则使用后面的数据更新行; 2.如果匹配则删除更新后的第二行,然后继续如果没有匹配则返回下一行并重新运行相同的进程。
如果匹配,则更高的行根据以下内容进行更新:
然后我删除下一行。
我的例子应该导致以下结果:
Heart | K | 1/1/2013 | 4/1/2013
Spade | Multiple | 2/1/2013 | 3/1/2013
Club | 4 | 2/1/2013 | 3/1/2013
为了做到这一切,我创建了两个表变量,将相同的数据插入到两个表变量中,然后在第二个(@ScheduleB)中循环查找匹配以更新第一个表中的行(@ScheduleA)。 然后我删除了@A中行下面的行(因为它与B相同)。 最后,当没有匹配时,我移动到@A的下一行开始该过程。 至少这是代码应该做的 - 见下文。
问题是性能是可怕的。 我考虑过使用Cursor,但不知道性能是否有帮助。
有什么建议么?
Declare @ScheduleA Table
(
RowNumber int,
Period nvarchar(MAX),
Program nvarchar(MAX),
ControlAccount Nchar(50),
WorkPackage Nchar(50),
CAM Nchar(50),
EVM Nchar(50),
Duration int,
BLStart datetime,
BLFinish datetime
)
Declare @ScheduleB Table
(
RowNumber int,
Period nvarchar(MAX),
Program nvarchar(MAX),
ControlAccount Nchar(50),
WorkPackage Nchar(50),
CAM Nchar(50),
EVM Nchar(50),
Duration int,
BLStart datetime,
BLFinish datetime
)
Insert INTO @ScheduleA
Select ROW_NUMBER() OVER(order by workpackage desc) as [Row], Period, Program,
ControlAccount, WorkPackage, CAM, EVM, Duration, BLStart, BLFinish
From ScheduleData
where program = @Program and period = @Period
Insert INTO @ScheduleB
Select ROW_NUMBER() OVER(order by workpackage desc) as [Row], Period, Program,
ControlAccount, WorkPackage, CAM, EVM, Duration, BLStart, BLFinish
From ScheduleData
where program = @Program and period = @Period
declare @i int = 1
declare @j int = 2
--Create a loop for the second variable that counts up to the last row of the B table
While @j < (select MAX(ROWNUMBER) + 1 from @ScheduleB)
Begin
--if the tables match by WorkPackage THEN
IF ((select WorkPackage from @ScheduleA where RowNumber = @i) =
(select workpackage from @ScheduleB where RowNumber = @j))
Begin
Update @ScheduleA
--Update the Schedule CAM, BLStart, BLFinish of the A table (if necessary)
set CAM =
Case
--Set values in @ScheduleA Column B based on logic
End,
BLStart =
Case
--Set values in @ScheduleA Column C based on logic
End,
BLFinish =
Case
--Set values in @ScheduleA Column D based on logic
End
Where RowNumber = @i
Delete from @ScheduleA
where RowNumber = @i + 1
set @j = @j + 1 --next row in B
End
ELSE
set @i = @i + 1
END
编辑:为了澄清,B列不是整数列,我只是以此为例,因为卡很容易理解。 我已经更新了专栏以包含K'。
根据您的要求,我认为像这样的解决方案可行:
SELECT
[column a],
CASE WHEN MAX([column b]) <> MIN([column b]) THEN 'multiple' ELSE CAST(MAX([column b]) AS NVARCHAR(10)) END,
MIN([column c]),
MAX([column d])
FROM Table
GROUP BY [column a]
编辑:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.