zoukankan      html  css  js  c++  java
  • 多种sql技术的综合应用(行转列、定制、批量数据产生)

    /*
    功能:按报表格式显示(行转列、定制、批量数据产生)
    作者:王召冠
    时间:2010-01-25 20:10
    说明:此例子也是多种sql技术的综合应用

    问题:假设有张考勤表(tb)如下:
    姓名     考勤日期      考勤次数
    张三    2010-01-01        2
    张三    2010-01-02        3
    张三    2010-01-03        1
    张三    2010-01-01        1
    李四    2010-01-02        2
    李四    2010-01-03        2

    想变成(得到如下结果):按指定时间段显示考勤报表
    姓名  2010-01-01 2010-01-02 2010-01-03 2010-01-04  ... 汇总     
    ---- ---------- ---------- ---------- ----------      ----
    李四        0           2          2          0        4
    张三        3           3          1          0        7
    汇总        3           5          3          0        11
    ----------------------------------------------------------
    */

    CREATE TABLE tb(vName NVARCHAR(10), dtDate DATETIME, iNum INT)
    GO

    INSERT  INTO tb 
    VALUES  ( '张三''2010-01-01'2 )
    INSERT  INTO tb
    VALUES  ( '张三''2010-01-02'3 )
    INSERT  INTO tb
    VALUES  ( '张三''2010-01-03'1 )
    INSERT  INTO tb
    VALUES  ( '张三''2010-01-01'1 )
    INSERT  INTO tb
    VALUES  ( '李四''2010-01-02'2 )
    INSERT  INTO tb
    VALUES  ( '李四''2010-01-03'2 )
    GO

    --SELECT    *
    --
    FROM    tb
        
    --SQL SERVER 动态SQL
    DECLARE @dtBegin DATETIME, @dtEnd DATETIME
    SELECT    @dtBegin = '2010-01-01', @dtEnd = '2010-01-31'

    SET NOCOUNT ON

    /*
    此处代码功能说明:
        根据指定的时间段,快速生成一个不间断的时间序列表
    具体实现特性说明:
        每循环一次生成2的n次方条记录,减少循环次数。
    注:
        从实际应用上来说,在此处没有太明显的效果和意义;仅仅体现一种优化算法而已。
    */
    DECLARE @iRank INT 
    SET @iRank = 1
    DECLARE @tmp TABLE(dtDate DATETIME)

    INSERT INTO @tmp ( dtDate ) VALUES ( @dtBegin ) 
    WHILE DATEADD(DAYPOWER(2, (@iRank-1)), @dtBegin<= @dtEnd
    BEGIN
        
    INSERT INTO @tmp ( dtDate )
        
    SELECT    DATEADD(DAYPOWER(2, (@iRank-1)), dtDate)
        
    FROM    @tmp 
        
    WHERE    DATEADD(DAYPOWER(2@iRank-1), dtDate) <= @dtEnd
        
        
    SET @iRank = @iRank + 1
    END

    /*
    此处代码功能说明:
        根据时间序列表,生成动态SQL
    注:
        之所以将动态sql分到两个变量里,主要是尽量避免8000个字符的限制
    */
    DECLARE @sql_a VARCHAR(8000)
    SET @sql_a = 'select vName'
    SELECT  @sql_a = @sql_a 
                    
    + ', sum(case dtDate when ''' + CONVERT(NVARCHAR(10), dtDate, 120)
                    
    + ''' then iNum else 0 end) [' + CONVERT(NVARCHAR(10), dtDate, 120+ ']'
    FROM    @tmp AS a
    SET @sql_a = @sql_a + ', sum(iNum) as iTotal from tb group by vName'
    --EXEC(@sql_a)

    DECLARE @sql_b VARCHAR(8000)
    SET @sql_b = 'select ''total'''
    SELECT    @sql_b = @sql_b + ', isnull((select sum(iNum) from tb where dtDate=''' + CONVERT(NVARCHAR(10), dtDate, 120+ '''), 0)'
    FROM    @tmp
    ORDER BY dtDate
    SET @sql_b = @sql_b + ', (select sum(iNum) from tb)'
    --EXEC(@sql_b)
    EXEC('select * from (' + @sql_a + ' union ' + @sql_b + ') as a order by a.iTotal'
    GO
  • 相关阅读:
    门禁控制系统的状态机-《实时控制软件设计》第二周作业
    [leetcode] Single Number
    [leetcode] Candy
    [leetcode] Gas Station
    [leetcode] Clone Graph
    [leetcode] Palindrome Partitioning II
    [leetcode] Palindrome Partitioning
    [leetcode] Surrounded Regions
    [leetcode] Sum Root to Leaf Numbers
    [leetcode] Longest Consecutive Sequence
  • 原文地址:https://www.cnblogs.com/zhaoguan_wang/p/1656069.html
Copyright © 2011-2022 走看看