使用同一个表中的数据组更新表中的行

时间:2015-01-30 13:13:08

标签: sql aggregate sybase

我有下表:

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年8月,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列,其值为(前12个月的NrOfThings的总和)每个月..

任何人都可以帮助我吗? Thx提前!

2 个答案:

答案 0 :(得分:0)

我已经实现了你的目标,但使用了游标。如果有人转换了这个或基于帖子集的逻辑,那就去吧。

我创建了一个名为#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

答案 1 :(得分:0)

这只是加入和分组的问题。查询应该是相对不言自明的。只需占据桌子的每一行,然后加入自己和之前的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 ...