首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

关于组合统计的有关问题()

2012-03-20 
关于组合统计的问题(高手进)本人想做一个组合统计,谁可以告诉我怎么实现表如下形式:idsexschoolgovernment

关于组合统计的问题(高手进)
本人想做一个组合统计,谁可以告诉我怎么实现

表如下形式:

id         sex         school         government       area    
-----------------------------------------
***         男           中学                 团员             北京
***         男           大学                 党员             上海
***         女           小学                 群众             北京
***         女           中学                 群众             天津
***         男           小学                 党员             上海
***         女           大学                 团员             北京
-------------------------------------------

现在想统计出一个列表,列表横轴和纵轴   分别可由以上4个字段中的一个或几个组合而成。

列表形式如下:

比如     由性别和学历组成的:

                                        性别
                      --------       -----------
                            男                   女

            小学         0                       1
 
            中学         2                       3
 
            大学         1                       2           (图中数字代表交叉统计的结果数)    


请高手帮帮忙。。。


[解决办法]
--借用libin_ftsafe(子陌红尘:当libin告别ftsafe) 数据一用

create table t(id varchar(6),sex varchar(6),school varchar(6),government varchar(6),area varchar(6))
insert into t select '*** ', '男 ', '中学 ', '团员 ', '北京 '
insert into t select '*** ', '男 ', '大学 ', '党员 ', '上海 '
insert into t select '*** ', '女 ', '小学 ', '群众 ', '北京 '
insert into t select '*** ', '女 ', '中学 ', '群众 ', '天津 '
insert into t select '*** ', '男 ', '小学 ', '党员 ', '上海 '
insert into t select '*** ', '女 ', '大学 ', '团员 ', '北京 '
go


1:
select
school,
团员=sum(case when government= '团员 ' then 1 else 0 end),
党员=sum(case when government= '党员 ' then 1 else 0 end),
群众=sum(case when government= '群众 ' then 1 else 0 end)
from t
group by school
2:


select
school,
北京=sum(case when area= '北京 ' then 1 else 0 end),
上海=sum(case when area= '上海 ' then 1 else 0 end),
天津=sum(case when area= '天津 ' then 1 else 0 end)
from t
group by school
3:
select ta.*,tb.北京,tb.上海,tb.天津 from
(
select
school,
团员=sum(case when government= '团员 ' then 1 else 0 end),
党员=sum(case when government= '党员 ' then 1 else 0 end),
群众=sum(case when government= '群众 ' then 1 else 0 end)
from t
group by school
) ta left join
(
select
school,
北京=sum(case when area= '北京 ' then 1 else 0 end),
上海=sum(case when area= '上海 ' then 1 else 0 end),
天津=sum(case when area= '天津 ' then 1 else 0 end)
from t
group by school
)tb
on ta.school=tb.school
4.
select ta.*,tb.北京,tb.上海,tb.天津 from
(
select
school,
团员=sum(case when government= '团员 ' then 1 else 0 end),
党员=sum(case when government= '党员 ' then 1 else 0 end),
群众=sum(case when government= '群众 ' then 1 else 0 end)
from t
group by school
) ta left join
(
select
school,
北京=sum(case when area= '北京 ' then 1 else 0 end),
上海=sum(case when area= '上海 ' then 1 else 0 end),
天津=sum(case when area= '天津 ' then 1 else 0 end)
from t
group by school
)tb
on ta.school=tb.school
union all
select school= '男 ',
团员=sum(case when (government= '团员 ' and sex= '男 ') then 1 else 0 end),
党员=sum(case when (government= '党员 ' and sex= '男 ') then 1 else 0 end),
群众=sum(case when (government= '群众 ' and sex= '男 ') then 1 else 0 end),
北京=sum(case when (government= '北京 ' and sex= '男 ') then 1 else 0 end),
上海=sum(case when (government= '上海 ' and sex= '男 ') then 1 else 0 end),
天津=sum(case when (government= '天津 ' and sex= '男 ') then 1 else 0 end)
from t
union all
select school= '女 ',
团员=sum(case when (government= '团员 ' and sex= '女 ') then 1 else 0 end),
党员=sum(case when (government= '党员 ' and sex= '女 ') then 1 else 0 end),
群众=sum(case when (government= '群众 ' and sex= '女 ') then 1 else 0 end),
北京=sum(case when (government= '北京 ' and sex= '女 ') then 1 else 0 end),
上海=sum(case when (government= '上海 ' and sex= '女 ') then 1 else 0 end),
天津=sum(case when (government= '天津 ' and sex= '女 ') then 1 else 0 end)
from t

--说明: 如果知道规则,然后修改成动态SQL就可以了.
--也可以用一个存储过程,根据不同需求,产生不同报表.

--drop table t
[解决办法]
--生成测试数据
create table t(id varchar(6),sex varchar(6),school varchar(6),government varchar(6),area varchar(6))
insert into t select '*** ', '男 ', '中学 ', '团员 ', '北京 '
insert into t select '*** ', '男 ', '大学 ', '党员 ', '上海 '
insert into t select '*** ', '女 ', '小学 ', '群众 ', '北京 '
insert into t select '*** ', '女 ', '中学 ', '群众 ', '天津 '
insert into t select '*** ', '男 ', '小学 ', '党员 ', '上海 '
insert into t select '*** ', '女 ', '大学 ', '团员 ', '北京 '
go

--创建存储过程
--@str_col:用于横向排列的列,以 ', '作为结束符
--@str_row:用户纵向分组的列,以 ', '作为结束符
create procedure sp_test(@str_col varchar(80),@str_row varchar(80))


as
begin
declare @sql varchar(8000),
@str1 varchar(8000),
@str2 varchar(8000),
@temp nvarchar(4000),
@col varchar(20),
@row varchar(20)

set @sql = ' '
set @str1= ' '

while charindex( ', ',@str_col)> 0
begin
set @col=left(@str_col,charindex( ', ',@str_col)-1)
set @str_col=stuff(@str_col,1,charindex( ', ',@str_col), ' ')

set @temp=N 'set @s= ' ' ' '
select @s=@s+ ' ',[ ' '+ '+@col+ '+ ' ']=sum(case '+@col+ ' when ' ' ' ' ' '+ '+@col+ '+ ' ' ' ' ' ' then 1 else 0 end) ' '
from t group by '+@col

exec sp_executesql @temp,N '@s varchar(8000) out ',@str2 out

set @str1=@str1+@str2
end

while charindex( ', ',@str_row)> 0
begin
set @row=left(@str_row,charindex( ', ',@str_row)-1)
set @str_row=stuff(@str_row,1,charindex( ', ',@str_row), ' ')

set @sql=@sql+ ' union all select '+@row+ ' as 项目 '+@str1+ ' from t group by '+@row
end

set @sql=stuff(@sql,1,11, ' ')
exec(@sql)
end
go


--执行测试
exec sp_test 'school,sex, ', 'government,area, '
go

--输出测试结果
/*
项目 大学 小学 中学 男 女
------ ----------- ----------- ----------- ----------- -----------
党员 1 1 0 2 0
群众 0 1 1 0 2
团员 1 0 1 1 1
北京 1 1 1 1 2
上海 1 1 0 2 0
天津 0 0 1 0 1
*/

--删除测试环境
drop table t
drop procedure sp_test
go

热点排行