【发布时间】:2017-07-07 00:38:56
【问题描述】:
这是遍历包含各种记录的表的 SQL 代码,该表包含开始和结束数据(如缓慢变化的维度)。在检查维度时,我们发现有时开始日期不在结束日期之后。因此,我们循环表格并重新创建开始/结束日期,以确保开始/结束日期实际上是可用日期的最小/最大值。但是这个过程需要很长时间才能处理 900 万行。我很想使用 while 循环,但无法确定保留最小值/最大值并检测 ID 中的开关。
DECLARE @MINDDEB Datetime
DECLARE @DDEB Datetime
DECLARE @DFIN Datetime
DECLARE @CECV float
DECLARE @AIDNEBHNPRPEP int
DECLARE @CETA float
DECLARE @AIDNEBHNPRAFI int
DECLARE @MAXDFIN Datetime
DECLARE @OLDCECV float
DECLARE @OLDAIDNEBHNPRPEP int
DECLARE @OLDCETA float
DECLARE @OLDAIDNEBHNPRAFI int
SET @MINDDEB=9999-12-31
SET @MAXDFIN=1835-12-31
drop table dbo.TBYDWHTEBHNPRAFIVRS_CURSORTABLE
--T2
SELECT DDEB, DFIN, CETA,AIDNEBHNPRAFI
into dbo.TBYDWHTEBHNPRAFIVRS_CURSORTABLE
FROM dbo.TBYDWHTEBHNPRAFIVRS
WHERE AIDNEBHNPRAFI=-1
ORDER BY AIDNEBHNPRAFI,DDEB
DECLARE T2_CURSOR CURSOR FOR
select DDEB, DFIN, CETA,AIDNEBHNPRAFI
from TBYDWHTEBHNPRAFIVRS
where DFIN>DDEB and BRRDDEL<>1 and CSTUVRS = 1 --and AIDNEBHNPRAFI in (1080,1033143,2311904)
order by AIDNEBHNPRAFI,DDEB,CETA,CECV
OPEN T2_CURSOR
FETCH NEXT FROM T2_CURSOR
INTO @DDEB, @DFIN, @CETA,@AIDNEBHNPRAFI
SET @OLDAIDNEBHNPRAFI=@AIDNEBHNPRAFI
SET @OLDCETA=@CETA
--SET @OLDCECV=@CECV
WHILE @@FETCH_STATUS = 0
BEGIN
if ( @OLDCETA=@CETA and @OLDAIDNEBHNPRAFI=@AIDNEBHNPRAFI)
BEGIN
--print 'entering first if'
IF (@MINDDEB>@DDEB)
BEGIN
SET @MINDDEB=@DDEB
END
IF (@MAXDFIN<@DFIN)
BEGIN
SET @MAXDFIN=@DFIN
END
END
--print ' OLD CECV '+convert(varchar(10),@OLDCECV) +' new CECV '+ convert(varchar(10),@CECV) +' OLDAID '+ convert(varchar(10),@OLDAIDNEBHNPRPEP) +' NEWAID '+ convert(varchar(10),@AIDNEBHNPRPEP)
-- +' NEWDDEB '+ convert(varchar(10),@DDEB,101) +' MINDDEB '+ convert(varchar(10),@MINDDEB,101) +' NEWDFIn '+ convert(varchar(10),@DFIN,101) +' MAXDFIN '+ convert(varchar(10),@MAXDFIN,101)
FETCH NEXT FROM T2_CURSOR
INTO @DDEB, @DFIN, @CETA,@AIDNEBHNPRAFI
if ( @OLDCETA<>@CETA or @OLDAIDNEBHNPRAFI<>@AIDNEBHNPRAFI)
BEGIN
INSERT INTO TBYDWHTEBHNPRAFIVRS_CURSORTABLE (DDEB, DFIN, CETA,AIDNEBHNPRAFI )
VALUES (@MINDDEB,@MAXDFIN,@OLDCETA,@OLDAIDNEBHNPRAFI)
SET @OLDAIDNEBHNPRAFI=@AIDNEBHNPRAFI
--SET @OLDCECV=@CECV
SET @OLDCETA=@CETA
SET @MINDDEB=@DDEB
SET @MAXDFIN=@DFIN
END
END
INSERT INTO TBYDWHTEBHNPRAFIVRS_CURSORTABLE (DDEB, DFIN, CETA,AIDNEBHNPRAFI )
VALUES (@MINDDEB,@MAXDFIN,@OLDCETA,@OLDAIDNEBHNPRAFI)
CLOSE T2_CURSOR;
DEALLOCATE T2_CURSOR;
这是源数据
DDEB DFIN CETA AIDNEBHNPRAFI
2006-03-01 00:00:00.000 2006-04-30 23:59:59.000 1 231272
2006-05-01 00:00:00.000 2006-11-30 23:59:59.000 1 231272
2006-12-01 00:00:00.000 2007-04-30 23:59:59.000 1 231272
2007-05-01 00:00:00.000 2008-04-30 23:59:59.000 1 231272
2008-05-01 00:00:00.000 2008-08-31 23:59:59.000 1 231272
2008-09-01 00:00:00.000 2008-10-31 23:59:59.000 2 231272
2008-11-01 00:00:00.000 2009-04-30 23:59:59.000 1 231272
2009-05-01 00:00:00.000 2010-01-31 23:59:59.000 1 231272
2010-02-01 00:00:00.000 9999-12-31 23:59:59.000 14 231272
这是我们用光标得到的结果
DDEB DFIN CETA AIDNEBHNPRAFI
2006-03-01 00:00:00.000 2008-08-31 23:59:59.000 1 231272
2008-09-01 00:00:00.000 2008-10-31 23:59:59.000 2 231272
2008-11-01 00:00:00.000 2010-01-31 23:59:59.000 1 231272
2010-02-01 00:00:00.000 9999-12-31 23:59:59.000 14 231272
【问题讨论】:
-
要么简化和最小化问题,要么雇用某人。
-
@jarlh,你的评论对我来说似乎是广告,因为你说 或雇用某人 ... :)
-
@Rahul,但我不是这个人。
-
这是一个很难读的时间和很长的帖子......尝试在 DECLARE T2_CURSOR CURSOR 之后使用 FAST_FORWARD 运行您的代码,并检查您是否有更好的性能
-
@Kostis,谢谢,我会试试的。
标签: sql sql-server while-loop cursor