示例: 
变动表changetb记录着仓库中各种产品的库存数量情况 ,变动表changetb记录着是产品在仓库的库存数量,只有当库存数量发生变化时,把当然记录的截止时间修改掉, 
再增加一条该产品的记录,记录起始日期,数量,
类别  产品名 起始日期    截止日期    库存数量      
A1      a    20080101    20080113    5 
A1      a    20080114    20080118    7 
产品在  20080101 到20080113这段期间,库存数据都是5,这段时间没有变化
在20080114这天发生了变化,就增加一条记录,这时数量为7 ,在  20080114 到20080118 这段期间 都是7这个在查某个产品的库存变化情况是相对来说是简单的,但想得到这个类别的库存情况,不知如何实现?
特请教,谢谢! create table  changetb 

clas char(2), 
product char(20), 
stdt char(8), 
eddt char(8), 
sl int 

示例数据:
类别  产品名 起始日期    截止日期    库存数量      
A1      a    20080101    20080113    5          
A1      a    20080114    20080118    7                  
A1      a    20080119    20080125    45    
A1      b    20080105    20080111    3                
A1      b    20080112    20080116    4 可能还有其它产品,不单单是a,b两种产品想得到如下这组数据?? 
类别A1总数量的变化情况 
类别 起始日期    截止日期    数量 
A1    20080101    20080104    5      --5    
A1    20080105    20080111    8      --5+3=8  因为20080105这天b产品数量变为3了            
A1    20080112    20080113    9      --5+4=9  因为20080112这天b产品数量变为4了
A1    20080114    20080116    11     --7+4=11  因为20080114这天a产品数量变为7了,而b为4           
A1    20080117    20080118    7       --7  因为b产品没有记录了,数量为0,而a这段时间为7       
A1    20080119    20080125    45      --45  因为b产品没有记录了,数量为0,而a这段时间为45   
谢谢各位了

解决方案 »

  1.   

    看了一下。结果的日期好像有点问题啊这个可能要先构造一张时间表,但是原来数据表中的时间是 (只取后三位) 101,105,111,112,113,114,116,118,119,125    起始日期    截止日期    数量 
    A1    20080101    20080104  (105-1)     
    A1    20080105    20080111   (如果是在112的基础上减1的话,原来的111怎么处理,如果只是把111提上来的话,又和第一行截止日期的算法不一
                                       样了)            
    A1    20080112    20080113        
    A1    20080114    20080116                 
    A1    20080117    20080118      (117的问题和上面一样)  
     A1    20080119    20080125                          也就是什么时候要加入新的时间,这个没规律啊。我是这么理解的。等高人
      

  2.   

    if object_id('[changetb]') is not null drop table [changetb]
    go
    create table [changetb]([clas] char(2),[product] char(20),[stdt] char(8),[eddt] char(8),[sl] int)
    insert [changetb]
    select 'a1','a','20080101','20080113',5 union all
    select 'a1','a','20080114','20080118',7 union all
    select 'a1','a','20080119','20080125',45 union all
    select 'a1','b','20080105','20080111',3 union all
    select 'a1','b','20080112','20080116',4--select * from [changetb]select id=identity(int,1,1),clas,dt into #
    from
    (
    select clas,dt=stdt from changetb
    union --all
    select clas,eddt from changetb
    union 
    select clas,convert(char(8),cast(stdt as datetime)-1,112) from changetb a
    where exists (select 1 from changetb where product<>a.product and stdt<a.stdt and eddt>a.stdt)
    union 
    select clas,convert(char(8),cast(eddt as datetime)+1,112) from changetb a
    where exists (select 1 from changetb where product<>a.product and stdt<a.stdt and eddt>a.stdt)
    ) t--select * from #select clas,stdt=min(dt),eddt=max(dt) into #1
    from #
    group by (id-1)/2,clas--select * from #1select a.clas,a.stdt,a.eddt,sl=sum(b.sl)
    from #1 a,changetb b
    where a.stdt<b.eddt and a.eddt>b.stdt 
    group by a.clas,a.stdt,a.eddt
    --测试结果:
    /*
    clas stdt     eddt     sl
    ---- -------- -------- -----------
    a1   20080101 20080104 5
    a1   20080105 20080111 8
    a1   20080112 20080113 9
    a1   20080114 20080116 11
    a1   20080117 20080118 7
    a1   20080119 20080125 45(6 行受影响)
    */
    drop table #
    drop table #1
      

  3.   

    没看明白
    select id=identity(int,1,1),clas,dt into #
    from
    (
        select clas,dt=stdt from changetb
        union --all
        select clas,eddt from changetb
        union 
        select clas,convert(char(8),cast(stdt as datetime)-1,112) from changetb a
        where exists (select 1 from changetb where product<>a.product and stdt<a.stdt and eddt>a.stdt)
        union 
        select clas,convert(char(8),cast(eddt as datetime)+1,112) from changetb a
        where exists (select 1 from changetb where product<>a.product and stdt<a.stdt and eddt>a.stdt)
    ) t因为   所有的eddt +1 就是 stdt ,cast(stdt as datetime)-1,112)
    与上面的eddt 是重复的,后面一句也类似我后来按实际数据来做,发现出来的数据也不对,
    谢谢我想修改一下表结构
    分类 产品 日期 产品入库量 库存情况 入库为正数,出库为负数 
    这样会不会简单一点呢,应该如何实现呢? 
    谢谢!
      

  4.   

    因为  所有的eddt +1 就是 stdt ,cast(stdt as datetime)-1,112) 
    与上面的eddt 是重复的,后面一句也类似 
    --所有的eddt+1就是stdt,这在结果表里的确如此,但在原表changetb里对某一大类(a1)而言,却并非如此。
    --因为需要按大类整合,有些时间点需要自己手动生成(20080104,20080117)。因此有了后面两个union。
    --union可以去除重复的记录,并隐式地按照select的字段进行排序。我后来按实际数据来做,发现出来的数据也不对, 
    谢谢 
    --按你现有的数据,我看不出哪里有错。
    --把你认为有错的数据贴出来看看。我想修改一下表结构 
    分类 产品 日期 产品入库量 库存情况 入库为正数,出库为负数 
    这样会不会简单一点呢,应该如何实现呢? 
    谢谢!
    --我没有设计库存表的实际经验,不敢妄言。
    --你可以重开大贴,给出你新的表结构、数据及想要的结果,必然有很多人给你提供方法。
    --你再将两种设计方式进行对照,取其优者。