有表结构和数据如下:
名称,类型,条件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,日期
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个月以上
基于这个基础之上,应该主要是对日期的判断和操作了!
您好,我们是“2006中国杰出数据库工程师评选”活动组委会。
您的帖子已经被我们转载到本次评选官方网站的“专家在线答疑”区。
http://www.bestdba.cn/match_discussion.aspx在那里,进入本次评选终选的30位数据库工程师将与您展开积极的互动。他们会为您的问题提供满意的答案,此外,您还可以在“专家在线答疑”区提出新的问题并参与讨论。您的帖子位于:
http://www.bestdba.cn/match_discussion3.aspx?pointid=489&pointid2=1&pointid3=5&pcount=stc非常感谢您对本次活动的支持!
--------------------------------------------------------------
--- 参考一下. ----------------------------------------
--取表的列属性.
---------------------------------------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-----------------------------------------------------------------------------
-- 日期,地区,指标 .. 转为具体的名称
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