[英]Updating rows in table with group of data from the same table
我的桌子如下:
Indicator Year Month FirstDayPeriod NrOfThings NmbrOfThingsPastYear
99 2013 1 Jan 1 2013 10858
99 2013 2 Feb 1 2013 8264
99 2013 3 Mar 1 2013 9716
99 2013 4 Apr 1 2013 8549
99 2013 5 May 1 2013 8144
99 2013 6 Jun 1 2013 7917
99 2013 7 Jul 1 2013 9585
99 2013 8 Aug 1 2013 7426
99 2013 9 Sep 1 2013 7877
99 2013 10 Oct 1 2013 9707
99 2013 11 Nov 1 2013 8925
99 2013 12 Dec 1 2013 13709
99 2014 1 Jan 1 2014 11183
99 2014 2 Feb 1 2014 8518
99 2014 3 Mar 1 2014 10545
99 2014 4 Apr 1 2014 9582
99 2014 5 May 1 2014 10278
99 2014 6 Jun 1 2014 9330
99 2014 7 Jul 1 2014 11366
99 2014 8 Aug 1 2014 9161
99 2014 9 Sep 1 2014 10651
99 2014 10 Oct 1 2014 11331
99 2014 11 Nov 1 2014 10624 126278
99 2014 12 Dec 1 2014 17958 130527
99 2015 1 Jan 1 2015 11431 130775
最后一列( NmbrOfThingsPastYear
)将是过去12个月中NrOfThings
的总数。 因此,2014年11月的NmbrOfThingsPastYear
由2014年11月,2014年10月,2014年9月等的NrOfThings
之和定义。。。直到2013年12月...我想做的就是用值更新此表中的NmbrOfThingsPastYear
列在这张桌子...
该语句提供了仅2014年11月的正确值:
SELECT
Indicator,
MAX(tsum.FirstDayPeriod),
SUM(tsum.AantalTaken)
FROM tempdb..TableAbove tsum
WHERE tsum.FirstDayPeriod > dateadd(mm, -12, '20141101')
AND tsum.FirstDayPeriod <= '20141101'
GROUP BY
Indicator
因此,我正在寻找一种可以NmbrOfThingsPastYear
更新表中每一行中NmbrOfThingsPastYear
列的值(前12个月NrOfThings
之和)的结构。
有谁能够帮助我? 提前谢谢!
我已经实现了您所追求的,但是使用了游标。 如果有人转换了该逻辑或基于后置集的逻辑,那就去吧。
我创建了一个名为#stuff的临时表,以复制您要尝试执行的操作。 如您所见,每个FirstDayPeriod日期都会循环,然后将前12个月的NrOfThings相加。 然后,基于FirstDayPeriod更新NrOfthingsPastYear。 您可以在此处轻松增加指标的范围,但以下内容应为您提供基础:
IF OBJECT_ID('tempdb..#Stuff') IS NOT NULL DROP TABLE #Stuff
GO
CREATE TABLE #Stuff
(Indicator int,
FirstDayPeriod datetime,
NrOfthings int,
NrOfthingspastyear int)
INSERT INTO #Stuff ( Indicator, FirstDayPeriod, NrOfthings, NrOfThingsPastYear)
VALUES (99, 'Jan 1 2013', '32432', 0),
(99, 'Feb 1 2013', '322', 0),
(99, 'Mar 1 2013', '312', 0),
(99, 'Apr 1 2013', '32432', 0),
(99, 'May 1 2013', '32', 0),
(99, 'Jun 1 2013', '32432', 0),
(99, 'Jul 1 2013', '32432', 0),
(99, 'Aug 1 2013', '32092', 0),
(99, 'Sep 1 2013', '2', 0),
(99, 'Oct 1 2013', '32432', 0),
(99, 'Nov 1 2013', '32432', 0),
(99, 'Dec 1 2013', '312', 0),
(99, 'Jan 1 2014', '32232', 0),
(99, 'Feb 1 2014', '32432', 0),
(99, 'Mar 1 2014', '32432', 0),
(99, 'Apr 1 2014', '3932', 0),
(99, 'May 1 2014', '3242', 0),
(99, 'Jun 1 2014', '32432', 0),
(99, 'Jul 1 2014', '324', 0),
(99, 'Aug 1 2014', '32432', 0),
(99, 'Sep 1 2014', '3532', 0),
(99, 'Oct 1 2014', '32432', 0),
(99, 'Nov 1 2014', '332', 0),
(99, 'Dec 1 2014', '3232', 0)
DECLARE @FirstDayPeriod datetime
DECLARE crs1 CURSOR
FOR
SELECT
FirstDayPeriod
FROM #Stuff
OPEN crs1
FETCH NEXT FROM Crs1 Into @FirstDayPeriod
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE
#Stuff
SET
NrOfThingsPastYear =(
SELECT
SUM(nrOfThings)
FROM
#Stuff
WHERE FirstDayPeriod > dateadd(mm, -12, @FirstDayPeriod)
AND FirstDayPeriod <= @FirstDayPeriod
)
WHERE
FirstDayPeriod = @FirstDayPeriod
FETCH NEXT FROM crs1 INTO @FirstDayPeriod
END
CLOSE crs1
DEALLOCATE crs1
SELECT * FROM #Stuff
这只是加入和分组的问题。 该查询应该相对不言自明。 只需占用表的每一行,并与自身和前11个月联接即可。 然后在该行的日期上分组(应该有12个),并添加连接的值。
SELECT tsum1.Indicator, tsum1.FirstDayPeriod,
Sum( tsum2.NrOfThings ) NmbrOfThingsPastYear
FROM TableAbove tsum1
join TableAbove tsum2
on tsum2.Indicator = tsum1.Indicator
and tsum2.FirstDayPeriod -- between now and a year ago
between DateAdd( Month, -11, tsum1.FirstDayPeriod )
and tsum1.FirstDayPeriod
group BY tsum1.Indicator, tsum1.FirstDayPeriod -- gather into 12-month chunks
having count(*) > 11 -- leave out any chunks of less than 12 months
order by tsum1.Indicator, tsum1.FirstDayPeriod;
having
子句可以防止部分结果,但是如果需要,可以忽略它。
由于存在分组,因此将其转换为update
语句会有些棘手。 如果没有其他问题,只需将此结果集反馈回与表的联接中并使用它。
这是小提琴 。 它使用SQL Server,因为SQLFiddle没有Sybase,但是它将关闭。
我想我应该在家安装Sybase ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.