有表结构和数据如下:
名称,类型,条件1,日期
1   ,A,   X,     2006-01-01 16:00:00
2   ,A,   X,     2006-01-01 16:00:00
3   ,A,   Y,     2006-01-02 16:00:00
4   ,A,   Y,     2006-01-02 16:00:00
5   ,B,   Y,     2006-01-01 16:00:00
6   ,B,   Y,     2006-01-01 16:00:00
7   ,B,   Y,     2006-01-02 16:00:00
8   ,B,   Z,     2006-01-03 16:00:00
9   ,B,   Z,     2006-01-04 16:00:00
10   ,C,  Z,     2006-01-01 16:00:00
11   ,C,  Z,     2006-01-02 16:00:00
12   ,C,  Z,     2006-01-03 16:00:00
...  , ..., ..., ...想实现如下两个存储过程:第一个:
1、指定时间范围从S到E(包括E)和条件1。
2、如果S到E小于等于一个月,则返回结果集:类型,总合计,区间合计,E,E-1,E-2,...,S (注意要倒排)
3、如果S到E大于一个月,则返回结果集:类型,总合计,区间合计,E,E-1,E-2,...,E-30,S到E-31合计
 3.1、从E倒排30天,按天统计类型的个数,再按从“S到E-31”的范围统计合计值。
4、总合计:不受时间范围约束的,所有数据的合计值。
5、区间合计:指定的时间范围的合计值,即从S到E(包括E)的合计值。第二个:
1、只需要先指定条件1
2、以数据的日期到当前日期差值,返回结果集:类型,总合计,1天,2天,3天,4天,5天,1~2周,2周~1个月,1个月以上

解决方案 »

  1.   

    http://community.csdn.net/Expert/topic/4939/4939437.xml?temp=.9773676
    基于这个基础之上,应该主要是对日期的判断和操作了!
      

  2.   

    --------------------------------------------------------------
    您好,我们是“2006中国杰出数据库工程师评选”活动组委会。
    您的帖子已经被我们转载到本次评选官方网站的“专家在线答疑”区。
    http://www.bestdba.cn/match_discussion.aspx在那里,进入本次评选终选的30位数据库工程师将与您展开积极的互动。他们会为您的问题提供满意的答案,此外,您还可以在“专家在线答疑”区提出新的问题并参与讨论。您的帖子位于:
    http://www.bestdba.cn/match_discussion3.aspx?pointid=489&pointid2=1&pointid3=5&pcount=stc非常感谢您对本次活动的支持!
    --------------------------------------------------------------
      

  3.   


    ---  参考一下. ----------------------------------------
    --取表的列属性.
    ---------------------------------------CREATE  VIEW VEW_GETDBCOL
    AS
    SELECT * FROM 
    (
    SELECT  
            [DBNAME]=D.NAME,
            [COLNAME]=A.NAME,
    [COLCODE]=B.XUSERTYPE,
    [COLTYPE]=B.NAME,[DATALEN]=COLUMNPROPERTY(A.ID,A.NAME,'PRECISION'),
    [IFNULL]=CASE WHEN A.ISNULLABLE=1 THEN '1'ELSE '' END  FROM SYSCOLUMNS A  
    LEFT JOIN SYSTYPES B ON A.XUSERTYPE=B.XUSERTYPE  INNER JOIN 
    SYSOBJECTS D ON A.ID=D.ID  AND D.XTYPE='U' AND  D.NAME<>'DTPROPERTIES'  
    ) AS TGO
    CREATE VIEW VEW_GETTEMPDBCOL
    AS
    SELECT * FROM 
    (
    SELECT  
            [DBNAME]=D.NAME,
            [COLNAME]=A.NAME,
    [COLCODE]=B.XUSERTYPE,
    [COLTYPE]=B.NAME,[DATALEN]=COLUMNPROPERTY(A.ID,A.NAME,'PRECISION'),
    [IFNULL]=CASE WHEN A.ISNULLABLE=1 THEN '1'ELSE '' END  FROM TEMPDB.DBO.SYSCOLUMNS A  
    LEFT JOIN TEMPDB.DBO.SYSTYPES B ON A.XUSERTYPE=B.XUSERTYPE  INNER JOIN 
    TEMPDB.DBO.SYSOBJECTS D ON A.ID=D.ID  AND D.XTYPE='U' AND  D.NAME<>'DTPROPERTIES'  
    ) AS T
    GO
    CREATE PROCEDURE PRC_CORSSQUERY
        @STRTABNAME AS VARCHAR(50) = 'VEW_BL_DATAITEM',          -- 此处放表名
        @STRCOL AS VARCHAR(50) = 'VAR_DATE',                   -- 表头分组依据字段  (横向字段,以系统编号作为依据,内部转化)
        @STRGROUP AS VARCHAR(50) = 'VAR_AREANAMECN',                    -- 分组字段         (纵向字段,直接取名称列)
        @STRSTATCOL AS VARCHAR(50) = 'FLO_VALUE',                   -- 被统计的字段     (值)
        @STRWHERE AS VARCHAR(256)='',                                   -- WHERE条件  (一定要带 WHERE 语句,如:WHERE 地区=''广州'' )  * 注意字符一定要用两个分号.
        @ISTOTAL  AS BIT=0,                     -- 是否合计
        @LANG INT=1,                     -- 语言  1 中文,2 英文
       -- @DATECOLFORMAT AS VARCHAR(32)='YYYY-MM-DD',               -- 如果表头的字段是日期,设置表头日期格式(注意:年为四个 Y,月为两个 M,日为两个 D )
        @TMPTABLE AS VARCHAR(255)=''                                -- 存放结果集的临时表名.
    AS BEGIN
        
        DECLARE @STRTMPCOL AS VARCHAR(256)
        DECLARE @STRSQL0 AS VARCHAR(8000)
        DECLARE @STRSQL1 AS VARCHAR(8000)
        DECLARE @STRSQL2 AS VARCHAR(8000)
        DECLARE @STRSQL3 AS VARCHAR(8000)
        DECLARE @STRSQL4 AS VARCHAR(8000)
        DECLARE @STRSQL5 AS VARCHAR(8000)
        DECLARE @STRSQL6 AS VARCHAR(8000)
        DECLARE @STRSQL7 AS VARCHAR(8000)
        DECLARE @STRSQL8 AS VARCHAR(8000)
        DECLARE @STRSQL9 AS VARCHAR(8000)
        DECLARE @STRSQL10 AS VARCHAR(8000)
        DECLARE @STRSQL11 AS VARCHAR(8000)
        DECLARE @STRSQL12 AS VARCHAR(8000)
        DECLARE @STRSQL13 AS VARCHAR(8000)
        DECLARE @STRSQL14 AS VARCHAR(8000)
        DECLARE @STRSQL15 AS VARCHAR(8000)
        DECLARE @STRSQL16 AS VARCHAR(8000)
        DECLARE @STRSQL17 AS VARCHAR(8000)
        DECLARE @STRSQL18 AS VARCHAR(8000)
        DECLARE @STRSQL19 AS VARCHAR(8000)
        DECLARE @STRSQL20 AS VARCHAR(8000)    DECLARE @STRCOLNAME AS VARCHAR(256)
        DECLARE @DATETYPE AS VARCHAR(2)
        DECLARE @COLTYPECODE AS INT
        DECLARE @STRID AS INT
        DECLARE @DATA1 AS VARCHAR(4)
        DECLARE @DATA2 AS VARCHAR(4)    
        DECLARE @DATA3 AS VARCHAR(4)
        DECLARE @TMPSTR AS VARCHAR(64) ----下面部分用于日期的格式化
    DECLARE @YEAR VARCHAR(12)
            DECLARE @MONTH VARCHAR(4)
            DECLARE @DAY VARCHAR(4)
            DECLARE @HOUR VARCHAR(4)
            DECLARE @MINUTE VARCHAR(4)
    DECLARE @SECOND VARCHAR(4)
            DECLARE @RETURNVAL VARCHAR(32)
            DECLARE @SWAPVAL VARCHAR(32)
    --------------------------------------------------    SELECT @STRID=1,@STRSQL0='',@STRSQL1='',@STRSQL2='',@STRSQL3='',@STRSQL4='',@STRSQL5='',@STRSQL6='',@STRSQL7='',@STRSQL8='',@STRSQL9='',
       @STRSQL10='',@STRSQL11='',@STRSQL12='',@STRSQL13='',@STRSQL14='',@STRSQL15='',@STRSQL16='',@STRSQL17='',@STRSQL18='',@STRSQL19='',@STRSQL20=''    EXECUTE ('DECLARE CORSS_CURSOR CURSOR FOR SELECT DISTINCT ' + @STRCOL + ' FROM ' + @STRTABNAME + ' ' + @STRWHERE + ' FOR READ ONLY ') --生成游标      SET NOCOUNT ON      IF @ISTOTAL=0 
              SET @STRSQL0 ='SELECT ' + @STRGROUP                                                         --查询的前半段(无合计)
          ELSE
              SET @STRSQL0 ='SELECT ' + @STRGROUP + ',SUM(' + @STRSTATCOL + ') AS [SUM_' + @STRSTATCOL + ']' --查询的前半段(有合计)      OPEN CORSS_CURSOR
          WHILE (0 = 0)   BEGIN
    FETCH NEXT FROM CORSS_CURSOR   --遍历游标,将列头信息放入变量@STRTMPCOL
    INTO @STRTMPCOL
    IF (@@FETCH_STATUS<>0) BREAK

    SET @STRID=@STRID+1
    SET @STRTMPCOL=CAST(@STRTMPCOL AS VARCHAR)
    SET @STRTMPCOL=REPLACE(@STRTMPCOL,CHAR(39),CHAR(39)+CHAR(39)) 
    SET @STRCOLNAME= @STRTMPCOL--  -- 取列格式.如果格式是日期型,则要转化 (已无日期格式, 该部分可以删除 )
    --  SELECT @COLTYPECODE=COLCODE FROM  VEW_GETDBCOL WHERE DBNAME=@STRTABNAME AND COLNAME=@STRCOL
    --  IF @COLTYPECODE=61 OR @COLTYPECODE=58 BEGIN  
    --          --日期类型,要转化
    --          SET @SWAPVAL= CONVERT(VARCHAR,CAST(@STRTMPCOL AS DATETIME),126)
    -- 
    --          SET @YEAR=SUBSTRING(@SWAPVAL,1,4)
    --  SET @MONTH=SUBSTRING(@SWAPVAL,6,2)
    --          SET @DAY=SUBSTRING(@SWAPVAL,9,2)
    -- 
    --          SET @STRCOLNAME=@DATECOLFORMAT
    --          SET @STRCOLNAME=REPLACE(@STRCOLNAME,'YYYY',@YEAR)
    --          SET @STRCOLNAME=REPLACE(@STRCOLNAME,'MM',@MONTH)
    --          SET @STRCOLNAME=REPLACE(@STRCOLNAME,'DD',@DAY)
    --  END-----------------------------------------------------------------------------
      

  4.   


                   --  日期,地区,指标 .. 转为具体的名称
    IF @STRCOL='VAR_DATE'   --如果表头是日期列.
                       SELECT @STRCOLNAME=DBO.FUN_CASTDATE(@STRCOLNAME,@LANG)
                    ELSE IF  @STRCOL='BIG_AREAAUTOID' BEGIN  -- 地区编号
        IF @LANG=1 
                            SELECT @TMPSTR=VAR_AREANAMECN FROM BS_AREA WHERE BIG_AREAAUTOID=@STRCOLNAME  --中文
                        ELSE IF @LANG=2 
    SELECT @TMPSTR=VAR_AREANAMEEN FROM BS_AREA WHERE BIG_AREAAUTOID=@STRCOLNAME  --英文
                        SET @STRCOLNAME=@TMPSTR
                        END
                    ELSE IF @STRCOL='BIG_GDLNAUTOID' BEGIN   -- 指标编号 
        IF @LANG=1 
                            SELECT @TMPSTR=VAR_GDLNNAMECN FROM BS_GDLN WHERE BIG_GDLNAUTOID=@STRCOLNAME  --中文
                        ELSE IF @LANG=2 
    SELECT @TMPSTR=VAR_GDLNNAMEEN FROM BS_GDLN WHERE BIG_GDLNAUTOID=@STRCOLNAME  --英文 
                        SET @STRCOLNAME=@TMPSTR
                    END     
    ------------------------------------------------------------------------------ IF @STRID<=50 
     SET @STRSQL1 = @STRSQL1 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF @STRID<=100 
     SET @STRSQL2 = @STRSQL2 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=150 
     SET @STRSQL3 = @STRSQL3 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN '+ @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=200 
     SET @STRSQL4 = @STRSQL4 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=250 
     SET @STRSQL5 = @STRSQL5 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=300 
     SET @STRSQL6 = @STRSQL6 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=350 
     SET @STRSQL7 = @STRSQL7 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=400 
     SET @STRSQL8 = @STRSQL8 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=450 
     SET @STRSQL9 = @STRSQL9 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=500 
     SET @STRSQL10 = @STRSQL10 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=550 
     SET @STRSQL11 = @STRSQL11 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=600 
     SET @STRSQL12 = @STRSQL12 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=650 
     SET @STRSQL13 = @STRSQL13 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=700 
     SET @STRSQL14 = @STRSQL14 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=750 
     SET @STRSQL15 = @STRSQL15 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=800 
     SET @STRSQL16 = @STRSQL16 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=850 
     SET @STRSQL17 = @STRSQL17 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=900 
     SET @STRSQL18 = @STRSQL18 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=950 
     SET @STRSQL19 = @STRSQL19 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
    ELSE IF  @STRID<=1000 
     SET @STRSQL20 = @STRSQL20 + ',SUM(CASE ' + @STRCOL + ' WHEN ''' + @STRTMPCOL + ''' THEN ' + @STRSTATCOL + ' ELSE NULL END) AS [' + @STRCOLNAME + ']' --构造查询
         END -- WHILE (0 = 0)     IF @TMPTABLE='' BEGIN --直接返回结果.
             EXECUTE ( @STRSQL0 + @STRSQL1 + @STRSQL2  + @STRSQL3 + @STRSQL4 + @STRSQL5 + @STRSQL6 + @STRSQL7 + @STRSQL8 + @STRSQL9  
                     + @STRSQL10 + @STRSQL11 + @STRSQL12  + @STRSQL13 + @STRSQL14 + @STRSQL15 + @STRSQL16 + @STRSQL17 + @STRSQL18 + @STRSQL19 + @STRSQL20  
             + ' FROM ' + @STRTABNAME + ' ' + @STRWHERE + ' GROUP BY ' + @STRGROUP)                      --执行
            END
         ELSE  BEGIN  --用临时表的形式返回
             EXECUTE ( @STRSQL0 + @STRSQL1 + @STRSQL2  + @STRSQL3 + @STRSQL4 + @STRSQL5 + @STRSQL6 + @STRSQL7 + @STRSQL8 + @STRSQL9  
                     + @STRSQL10 + @STRSQL11 + @STRSQL12  + @STRSQL13 + @STRSQL14 + @STRSQL15 + @STRSQL16 + @STRSQL17 + @STRSQL18 + @STRSQL19 + @STRSQL20  
             + ' INTO ' +@TMPTABLE + ' FROM ' + @STRTABNAME + ' ' + @STRWHERE + ' GROUP BY ' + @STRGROUP) --执行
         END      IF @@ERROR <>0 RETURN @@ERROR    --如果出错,返回错误代码
          CLOSE CORSS_CURSOR
          DEALLOCATE CORSS_CURSOR RETURN 0 --释放游标,返回0表示成功ENDGO