用sql 可以生成动态报表吗?
搜索一下动态报表,大部分都是用编程语言实现的,我试想,可不可以用sql 语句完成呢?
目的是想不用写代码生成类似的报表,尤其是财务报表
表如下
T1:
key_seqproject_name
1 '实发工资 '
2 '扣款项 '
T2:
key_seqdetail_namelink_keycolname
1 '基本工资 '1 'col2 '
2 '奖金 '1 'col1 '
3 '扣考勤 '2 'col3 '
4 '扣税 '2 'col5 '
T3:
key_seqemployeecol1col2col3col4col5
1 'a '1005010020
2 'b '1003020020
3 'c '1002010020
想得到这样的结果:(注意,我是想要把T1,T2中的project_name,detail_name拿过来做字段名的,还有就是请不要拘泥于测试数据,
希望各位能够做的比较灵活
)
-------实发工资----------------扣款项-----
员工基本工资 '奖金 扣考勤扣税
'a '50100 10 20
'b '30100 20 20
'c '20100 10 20
[解决办法]
create table T1(key_seqint,project_name varchar(10))
insert into T1 select 1, '实发工资 '
insert into T1 select 2, '扣款项 '
create table T2(key_seqint,detail_namevarchar(10),link_key int,colname varchar(10))
insert into T2 select 1, '基本工资 ',1, 'col2 '
insert into T2 select 2, '奖金 ',1, 'col1 '
insert into T2 select 3, '扣考勤 ',2, 'col3 '
insert into T2 select 4, '扣税 ',2, 'col5 '
create table T3(key_seqint,employee varchar(4),col1 int,col2 int,col3 int,col4 int,col5 int)
insert into T3 select 1, 'a ',100,50,10,0,20
insert into T3 select 2, 'b ',100,30,20,0,20
insert into T3 select 3, 'c ',100,20,10,0,20
go
declare @sql varchar(8000)
set @sql= ' '
select @sql=@sql+ ',[ '+a.project_name+ '-- '+b.detail_name+ ']= '+b.colname
from T1 a,T2 b where a.key_seq=b.link_key
set @sql= 'select employee '+@sql+ ' from T3 '
exec(@sql)
/*
employee 实发工资--基本工资 实发工资--奖金 扣款项--扣考勤 扣款项--扣税
-------- ----------- ----------- ----------- -----------
a 50 100 10 20
b 30 100 20 20
c 20 100 10 20
*/
go
drop table T1,T2,T3
go
[解决办法]
SQL Server 2000不支持双表头,在我给出的例子里我把双表头合并了一下。
建议在应用程序中实现双表头的现实。
[解决办法]
--创建测试环境
create table T1(key_seq int,project_name varchar(20))
create table T2(key_seq int,detail_name varchar(20),link_key int,colname varchar(20))
create table T3(key_seq int,employee varchar(10),col1 int,col2 int,col3 int,col4 int,col5 int)
--插入测试数据
insert T1(key_seq,project_name)
select '1 ', '实发工资 ' union all
select '2 ', '扣款项 '
insert T2(key_seq,detail_name,link_key,colname)
select '1 ', '基本工资 ', '1 ', 'col2 ' union all
select '2 ', '奖金 ', '1 ', 'col1 ' union all
select '3 ', '扣考勤 ', '2 ', 'col3 ' union all
select '4 ', '扣税 ', '2 ', 'col5 '
insert T3(key_seq,employee,col1,col2,col3,col4,col5)
select '1 ', 'a ', '100 ', '50 ', '10 ', '0 ', '20 ' union all
select '2 ', 'b ', '100 ', '30 ', '20 ', '0 ', '20 ' union all
select '3 ', 'c ', '100 ', '20 ', '10 ', '0 ', '20 '
--求解过程
declare @sql varchar(8000) set @sql = 'select employee '
select @sql = @sql + ', '+ x.name + ' as ' + x.detail_name
from(
select _sc.name,_t.detail_name,_t.key_seq
from syscolumns _sc
join T2 _t on _t.colname = _sc.name
where id = object_id( 'T3 ')
) x
select @sql = @sql + ' from T3 '
exec(@sql)
--删除测试环境
drop table T1,T2,T3
/*--测试结果
employee 基本工资 奖金 扣考勤 扣税
---------- ----------- ----------- ----------- -----------
a 50 100 10 20
b 30 100 20 20
c 20 100 10 20
*/
[解决办法]
唉,我想的太复杂了。
[解决办法]
动态报表通常的处理是借助存储过程中的动态SQL来实现,类似楼主这样的动态交叉表问题,楼上用的是SQL Server 2000中最常见的解决方案。
[解决办法]
--借用下楼上数据.:)
create table T1(key_seqint,project_name varchar(10))
insert into T1 select 1, '实发工资 '
insert into T1 select 2, '扣款项 '
create table T2(key_seqint,detail_namevarchar(10),link_key int,colname varchar(10))
insert into T2 select 1, '基本工资 ',1, 'col2 '
insert into T2 select 2, '奖金 ',1, 'col1 '
insert into T2 select 3, '扣考勤 ',2, 'col3 '
insert into T2 select 4, '扣税 ',2, 'col5 '
create table T3(key_seqint,employee varchar(4),col1 int,col2 int,col3 int,col4 int,col5 int)
insert into T3 select 1, 'a ',100,50,10,0,20
insert into T3 select 2, 'b ',100,30,20,0,20
insert into T3 select 3, 'c ',100,20,10,0,20
go
select employee,
[实发工资---基本工资]=max([实发工资---基本工资]),[实发工资---奖金]=max([实发工资---奖金]),
[扣款项---扣考勤]=max([扣款项---扣考勤]),[扣款项---扣税]=max([扣款项---扣税]) from
(
select * from
(
SELECT *
FROM
(SELECT employee, col1, col2, col3, col4, col5
FROM T3) p
UNPIVOT
(列值 FOR 列 IN
(col1, col2, col3, col4, col5)
)AS unpvt
)tb
left join
(
select b.project_name+ '--- '+detail_name as names,colname from T2 a inner join T1 b
on a.link_key=b.key_seq
)tc
on tb.列=tc.colname
) td
pivot
(max(列值)
for names in ([实发工资---奖金],[实发工资---基本工资],[扣款项---扣考勤],[扣款项---扣税])
) as pt
group by employee
/*
employee 实发工资---基本工资 实发工资---奖金 扣款项---扣考勤 扣款项---扣税
-------- ----------- ----------- ----------- -----------
a 50 100 10 20
b 30 100 20 20
c 20 100 10 20
警告: 聚合或其他 SET 操作消除了空值。
(3 行受影响)
*/
drop table t1
drop table t2
drop table t3
[解决办法]
晕~~~2000这么简单~~~呵呵...不好意思啊~~~
楼主参考2000的方法吧~~~