最好是SQL后台只提供记录,报表格式有前台去做实在要做就在你生成这些记录的地方加上 union select 小计='小计',...,sum() ... union select 合计='合计',...,sum() ...
合计和小计的名称转换不了,头疼ing,实在不行你就在程序中转吧,:( 另外,日期的跨度太大就无法实现了,因为@s只支持最大8000字节try: ---------------------------------------------------------------------------- declare @date1 datetime,@date2 datetime,@s varchar(8000),@d char(10),@i int set @date1 = '2005-06-01' set @date2 = '2005-06-15' set @s = '' set @i = datediff(d,@date1,@date2)+1 while @date1<=@date2 begin set @d = convert(char(10),@date1,120) set @s = @s + ',['+rtrim(month(@date1))+'月'+rtrim(day(@date1))+'日'+'正常加班]=sum(case when 类型=''正常加班'' and 日期 = '''+@d+''' then 1 else 0 end)' + ',['+rtrim(month(@date1))+'月'+rtrim(day(@date1))+'日'+'双休加班]=sum(case when 类型=''双休加班'' and 日期 = '''+@d+''' then 1 else 0 end)' + ',['+rtrim(month(@date1))+'月'+rtrim(day(@date1))+'日'+'假日加班]=sum(case when 类型=''假日加班'' and 日期 = '''+@d+''' then 1 else 0 end)'
set @date1 = dateadd(day,1,@date1) endset @s = 'select t.* from (select a.代码,a.姓名,a.部门'+@s +',正常加班小计=sum(case 类型 when ''正常加班'' then 1 else 0 end)' +',双休加班小计=sum(case 类型 when ''双休加班'' then 1 else 0 end)' +',假日加班小计=sum(case 类型 when ''假日加班'' then 1 else 0 end)' +',汇总=sum(1)' +',平均=(sum(1)+0.0)/'+rtrim(@i) +' from xemp_entry a,申请记录表 b,xemp_entry_001 c where a.xid = b.xempid and a.xid=c.xempid' +' group by a.部门,a.代码,a.姓名 with rollup) t where 代码 is null or 姓名 is not null' print @sexec(@s)
BUG还是比较严重的,如果可能的话,先将就着用吧,呵呵。
1. 为源数据打开 一个,游标置首位.并申请一个和源数据一样的 临时行变量 tmp, 置空值 申请一个和目标展现表一样结构的 行变量 个人 grxj , 用来存储个人小计 申请一个和目标展现表一样结构的 行变量 xjRec, 用来存储部门小计 申请一个和目标展现表一样结构的 行变量 hjRec, 用来存储合计2. 读取当前游标的数据值 Curr , 判断是while( 游标未结束 ) { if (Curr.部门 != tmp.部门 ) { if (null != tmp ) { a. 将个人小计 grxj 写入当前行 b. 结果集合 添加一行 c. 将xjRec 部门小计值 写入当前行 d. 将个人小计, 部门小计 清零 } //新的部门的第一个人 a.结果集合 添加一行 b.将Curr中相应的数据填入结果集当前行纪录的相应列 c.累加 个人小计 grxj , 统计部门小计 xjRec , 统计合计值hjRec } else { //判断 是否同一个人,同一个人则不需要添加新行 if (Curr.人名 != tmp.人名) { a. 将个人小计 写入结果集 当前行 b. 清空个人小计 c. 并新添加一行 } a.将Curr中相应的数据填入结果集当前行纪录的相应列 b. 累加 个人小计 grxj , 统计部门小计 xjRec , 统计合计值hjRec } 移动游标到下一行} //封口 a. 将个人小计 grxj 写入当前行 b. 结果集合 添加一行 c. 将xjRec 部门小计值 写入当前行 d. 结果集合 添加一行 e. 将hjRec 合计值 写入当前行3. 返回该结果集 over这个流程适合于 前端 的 展示如果转化成存储过程的话。我不知道 存储过程 能不能返回 自定义的结果集 , (里面涉及到行转列的问题,网上很多资料能够解决) 其实 只需要确定存储过程能够返回自定义的 结果集 就能够将 上诉的流程 实现 而且效率也应该当是很高的(只需要查询一遍数据库)。 如果存储过程不行的话那么在前端也能够使用这个流程。 如果要把这个流程融合到报表里的话,有点难度。可能需要动态创建一个临时表来存储才能够满足要求。 但是如果采用报表的话, 那数据源采用 动态sql 就可以了,报表支持分组统计,小计,合计。这个倒是很简单。
还有xemp_entry_001表与xemp_entry表不一致.
如
xemp_entry表中的记录:3 c CC 电算科
xemp_entry_001表中的记录:3 C
其中一个表放我们要的结果,另一个表作为临时变量,
然后不断的drop那张临时表.
还有xemp_entry_001表与xemp_entry表不一致.
如
xemp_entry表中的记录:3 c CC 电算科
xemp_entry_001表中的记录:3 C
xemp_entry_001里只存放了两个字段xempid,代码这里的xempid对应xemp_entry表里的xid
已经写了84行了.
搞出来也没意思.还是等人家好的方法吧.
filebat 谢您了
A AA 人事科 4 0 0 …. 14 …. 2 15 8 14 2 24 1.60
B BB 人事科 4 14 0 … 0 …. 0 15 4 14 0 18 1.20
要在这行插入小计
C CC 电算科 5 0 4 … 0 …. 0 15 9 0 0 9 0.36
要在这行插入小计
g gg pcp 2 0 0 … 0 …. 0 15 14 2 0 16 1.07
要在这行插入小计
最后一行要有全部的合计
union
select 小计='小计',...,sum() ...
union
select 合计='合计',...,sum() ...
另外,日期的跨度太大就无法实现了,因为@s只支持最大8000字节try:
----------------------------------------------------------------------------
declare @date1 datetime,@date2 datetime,@s varchar(8000),@d char(10),@i int
set @date1 = '2005-06-01'
set @date2 = '2005-06-15'
set @s = ''
set @i = datediff(d,@date1,@date2)+1
while @date1<=@date2
begin
set @d = convert(char(10),@date1,120)
set @s = @s + ',['+rtrim(month(@date1))+'月'+rtrim(day(@date1))+'日'+'正常加班]=sum(case when 类型=''正常加班'' and 日期 = '''+@d+''' then 1 else 0 end)'
+ ',['+rtrim(month(@date1))+'月'+rtrim(day(@date1))+'日'+'双休加班]=sum(case when 类型=''双休加班'' and 日期 = '''+@d+''' then 1 else 0 end)'
+ ',['+rtrim(month(@date1))+'月'+rtrim(day(@date1))+'日'+'假日加班]=sum(case when 类型=''假日加班'' and 日期 = '''+@d+''' then 1 else 0 end)'
set @date1 = dateadd(day,1,@date1)
endset @s = 'select t.* from (select a.代码,a.姓名,a.部门'+@s
+',正常加班小计=sum(case 类型 when ''正常加班'' then 1 else 0 end)'
+',双休加班小计=sum(case 类型 when ''双休加班'' then 1 else 0 end)'
+',假日加班小计=sum(case 类型 when ''假日加班'' then 1 else 0 end)'
+',汇总=sum(1)'
+',平均=(sum(1)+0.0)/'+rtrim(@i)
+' from xemp_entry a,申请记录表 b,xemp_entry_001 c where a.xid = b.xempid and a.xid=c.xempid'
+' group by a.部门,a.代码,a.姓名 with rollup) t where 代码 is null or 姓名 is not null'
print @sexec(@s)
1. 为源数据打开 一个,游标置首位.并申请一个和源数据一样的 临时行变量 tmp, 置空值
申请一个和目标展现表一样结构的 行变量 个人 grxj , 用来存储个人小计
申请一个和目标展现表一样结构的 行变量 xjRec, 用来存储部门小计
申请一个和目标展现表一样结构的 行变量 hjRec, 用来存储合计2. 读取当前游标的数据值 Curr , 判断是while( 游标未结束 )
{
if (Curr.部门 != tmp.部门 )
{
if (null != tmp )
{
a. 将个人小计 grxj 写入当前行
b. 结果集合 添加一行
c. 将xjRec 部门小计值 写入当前行
d. 将个人小计, 部门小计 清零
}
//新的部门的第一个人 a.结果集合 添加一行
b.将Curr中相应的数据填入结果集当前行纪录的相应列
c.累加 个人小计 grxj , 统计部门小计 xjRec , 统计合计值hjRec }
else
{
//判断 是否同一个人,同一个人则不需要添加新行
if (Curr.人名 != tmp.人名)
{
a. 将个人小计 写入结果集 当前行
b. 清空个人小计
c. 并新添加一行
}
a.将Curr中相应的数据填入结果集当前行纪录的相应列
b. 累加 个人小计 grxj , 统计部门小计 xjRec , 统计合计值hjRec
} 移动游标到下一行} //封口
a. 将个人小计 grxj 写入当前行
b. 结果集合 添加一行
c. 将xjRec 部门小计值 写入当前行
d. 结果集合 添加一行
e. 将hjRec 合计值 写入当前行3. 返回该结果集 over这个流程适合于 前端 的 展示如果转化成存储过程的话。我不知道 存储过程 能不能返回 自定义的结果集 ,
(里面涉及到行转列的问题,网上很多资料能够解决)
其实 只需要确定存储过程能够返回自定义的 结果集 就能够将 上诉的流程 实现
而且效率也应该当是很高的(只需要查询一遍数据库)。
如果存储过程不行的话那么在前端也能够使用这个流程。
如果要把这个流程融合到报表里的话,有点难度。可能需要动态创建一个临时表来存储才能够满足要求。
但是如果采用报表的话,
那数据源采用 动态sql 就可以了,报表支持分组统计,小计,合计。这个倒是很简单。