zoukankan      html  css  js  c++  java
  • 解决一条高难度的,关于时间段 数据汇总问题

    假设有如下两张表:
    表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

  • 相关阅读:
    java OA系统 自定义表单 流程审批 电子印章 手写文字识别 电子签名 即时通讯
    flowable 获取当前任务流程图片的输入流
    最新 接口api插件 Swagger3 更新配置详解
    springboot 集成 activiti 流程引擎
    java 在线考试系统源码 springboot 在线教育 视频直播功能 支持手机端
    阿里 Nacos 注册中心 配置启动说明
    springboot 集成外部tomcat war包部署方式
    java 监听 redis 过期事件
    springcloudalibaba 组件版本关系
    java WebSocket 即时通讯配置使用说明
  • 原文地址:https://www.cnblogs.com/wghao/p/747053.html
Copyright © 2011-2022 走看看