• 解决一条高难度的,关于时间段 数据汇总问题


    假设有如下两张表:
    表A:
    id    type    begin_date   end_date  count
    ---------------------------------------------
    1     A      2007-5-12     2007-5-14   30
    2     A      2007-5-11     2007-5-13   20
    3     B      2007-5-12     2007-5-15   50
    4     B      2007-5-13     2007-5-14   30

    表示 从begin_date到end_date的时间段内,每天都会有30数量的A,其它行都是相同的意思

    表B:(消耗表)
    id   type   use_date  count
    ------------------------------
    1    A      2007-5-11  15
    2    A      2007-5-12  15
    3    B      2007-5-12  20
    4    B      2007-5-13  30

    表A和表B的id没有关系,现在要根据某一时间段,查询剩余数,比如:2007-5-11到2007-5-14的结余数量:

    得到余下结果:
    id type 2007-5-11  2007-5-12  2007-5-13 2007-5-14
    1  A      5          35         50         30
    2  B      0          30         50         80

    其中2007-5-12,5-13,5-14是根据条件动态生成。。。。

    怎么比较高效的实现上述功能。。。我想到的需要循环好几次,实在是够理想,请朋友们一起想想,或者,通过修改表结构,达到相同的目的

    解决方法:

    create table TableA(id int, type char(1), begin_date smalldatetime, end_date smalldatetime[count] int)
    insert TableA select 1 ,'A''2007-5-12''2007-5-14'30
    union all select 2 ,'A''2007-5-11''2007-5-13'20
    union all select 3 ,'B''2007-5-12''2007-5-15'50
    union all select 4 ,'B''2007-5-13''2007-5-14'30
    go
    create table TableB(id int, type char(1), use_date smalldatetime[count] int)
    insert TableB select 1 ,'A''2007-5-11'15
    union all select 2 ,'A''2007-5-12'15
    union all select 3 ,'B''2007-5-12'20
    union all select 4 ,'B''2007-5-13'30
    go

    DECLARE @BeginDate smalldatetime     --开始日期
    DECLARE @EndDate smalldatetime      --结束日期
    DECLARE @TmpDate smalldatetime
    DECLARE @EXECUTE_SQL nvarchar(4000)        --
    SELECT @BeginDate='2007-5-11'
        ,
    @EndDate='2007-5-14'
        ,
    @TmpDate=@BeginDate
        ,
    @EXECUTE_SQL='SELECT type'

    CREATE TABLE #T(TDate smalldatetime--构造临时表,用于分类统计,和构造行列转换语句
    WHILE @TmpDate<=@EndDate
        
    BEGIN
            
    INSERT INTO #T SELECT @TmpDate
            
    SELECT @EXECUTE_SQL=@EXECUTE_SQL+',SUM(CASE TDATE WHEN '''+CONVERT(nchar(10),@TmpDate,120)+''' THEN [count] ELSE 0 END) AS ['+CONVERT(nchar(10),@TmpDate,120)+']'
                ,
    @TmpDate=DATEADD(day,1,@TmpDate)
            
        
    END
    SET @EXECUTE_SQL=@EXECUTE_SQL+CHAR(10)+'FROM #T1 GROUP BY type'

    --没有行列转换前统计,插入表#T1
    SELECT type,TDate,SUM([count]AS [count] INTO #T1
        
    FROM (
            
    SELECT type,TDate,[count] FROM TableA CROSS JOIN #T WHERE (begin_date BETWEEN  @BeginDate AND @EndDate
                
    OR  end_date BETWEEN  @BeginDate AND @EndDate)
                
    AND TDate BETWEEN begin_date AND end_date
            
    UNION ALL SELECT type,use_date,-[count] FROM TableB WHERE use_date BETWEEN  @BeginDate AND @EndDate
            ) 
    AS A
        
    GROUP BY type,TDate
        
    ORDER BY type,TDate
    EXECUTE@EXECUTE_SQL)        
    DROP TABLE TableA,TableB,#T,#T1
    go

    /*
    type    2007-05-11    2007-05-12    2007-05-13    2007-05-14
    ---------------------------------------------------------------------------
    A        5    35        50        30
    B        0    30        50        80
    */

    以上方法没有使用到游标,只是使用到2张临时表就可以拷定,其实也可以使用1个临时表就可以,只不过为了方便更好的了解计算方法,把分类统计过程独立出来。
    这方法虽然语句有点长吧,但我相信比使用游标更快。


    问题来源:http://community.csdn.net/Expert/topic/5532/5532084.xml?temp=.7621729

  • 相关阅读:
    开始学习编写用于 Windows SideShow 设备的小工具【转】
    Windows Mobile 6.5 Developer Tool Kit 下载
    Microsoft Security Essentials 微软免费杀毒软件下载
    SQL Server 2008 空间数据存储摘抄(SRID 点 MultiPoint LineString MultiLineString 多边形 MultiPolygon GeometryCollection)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (2)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (4)
    负载测试、压力测试和性能测试的异同
    Windows Server 2008 Vista Sidebar Gadget (侧边栏小工具) 入门开发实例
    Silverlight Tools 安装失败 解决办法
    SQL Server 2008 空间数据库 空间索引概念及创建(取自帮助)
  • 原文地址:https://www.cnblogs.com/wghao/p/747053.html
Copyright © 2020-2023  润新知