您好,欢迎来到筏尚旅游网。
搜索
您的当前位置:首页SQL交叉表实例

SQL交叉表实例

来源:筏尚旅游网




[2005-4-8 10:36:35 | By: 孤独的猎人]

SQL交叉表实例

建表:

在查询分析器里运行:
CREATETABLE [Test] (
[id][int] IDENTITY (1, 1) NOT NULL ,
[name][nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[subject][nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[Source][numeric](18, 0) NULL
)ON [PRIMARY]
GO

INSERTINTO [test] ([name],[subject],[Source]) values (N'张三',N'语文',60)

INSERTINTO [test] ([name],[subject],[Source]) values (N'李四',N'数学',70)

INSERTINTO [test] ([name],[subject],[Source]) values (N'王五',N'英语',80)

INSERT INTO [test] ([name],[subject],[Source]) values(N'王五',N'数学',75)

INSERTINTO [test] ([name],[subject],[Source]) values (N'李四',N'语文',80)

INSERT INTO [test] ([name],[subject],[Source]) values(N'张三',N'英语',100) INSERT INTO [test] ([name],[subject],[Source]) values(N'王五',N'语文',57)

Go

交叉表语句的实现:

--用于:交叉表的列数是确定的
selectname,sum(case subject when '数学'then source else 0 end) as '数学',sum(case subject when '英语'then source else 0 end) as '英语',
sum(casesubject when '语文'then source else 0 end) as '语文'
fromtest
groupby name

--用于:交叉表的列数是不确定的

declare @sql varchar(8000)



set @sql = 'select name,'

select @sql = @sql + 'sum(case subject when '''+subject+'''



thensource else 0 end) as '''+subject+''','

from(select distinct subject from test) as a

select@sql = left(@sql,len(@sql)-1) + ' from test group by name'

exec(@sql)

go

一个通用的针对单表用的交叉表存储过程

传入几个参数:

@TableNamevarchar(16) --表名
@纵轴varchar(20)--交叉表最左面的列
@横轴varchar(10)--交叉表最上面的列
@表体内容numeric(10,2)--交叉表的数字内容
@是否加横向合计bit--1时在交叉表横向最右边加横向合计
@是否家纵向合计bit--1时在交叉表纵向最下边加纵向合计

思路:
1、取得disinct横轴字段后,取得唯一的横轴字段表

select科室,sum(case(横轴字段表.....).......)from @tablename group by 科室 2、根据横轴的唯一字段内容,循环整个表后动态生成一个Sql语句,

3、根据参数是否合计,分别加合计字段,求出横向合计和纵向合计

您看这个思路行吗?但有一个就是横轴不能太多,多了Sql可能会超过8000字符。一般不会这么多,如果太多就把横轴变为exec 生成的Sql

纵轴,总之取字段较少的做横轴,这个就是传参数时的问题了。

如果弄成了,这个在一定的范围内应该是比较通用的了。对不!

这是我的思路,具体写的时候,感觉到Sql的组合比较麻烦,能帮我写一下吗?

============================================================

ifexists (select * from dbo.sysobjects where id =object_id(N'[dbo].[p_qry]') and OBJECTPROPERTY(id, N'IsProcedure') =1) drop procedure [dbo].[p_qry]
GO

/*--生成交叉表的简单通用存储过程

根据指定的表名,纵横字段,统计字段,自动生成交叉表并可根据需要生成纵横两个方向的合计

注意,横向字段数目如果大于纵向字段数目,将自动交换纵横字段如果不要此功能,则去掉交换处理部分





--邹建204.06--*/

/*--调用示例

execp_qry 'syscolumns','id','colid','colid','name like ''s%''',1,1
--*/

createproc p_qry
@TableNamesysname, --表名
@纵轴sysname,--交叉表最左面的列
@横轴sysname,--交叉表最上面的列
@表体内容sysname,--交叉表的数数据字段
@条件varchar(1000),--查询的处理条件
@是否加横向合计bit,--1时在交叉表横向最右边加横向合计
@是否家纵向合计bit--1时在交叉表纵向最下边加纵向合计
as
declare@s nvarchar(4000),@sql varchar(8000)

--规范条件
set@条件=casewhen @条件<>''then ' where ('+@条件+')'else '' end

--判断横向字段是否大于纵向字段数目,如果是,则交换纵横字段
set@s='declare @a sysname

select @a=@纵轴,@纵轴=@横轴,@横轴=@a'exec sp_executesql @s if(select case when count(distinct['+@纵轴+'])from ['+@TableName+']'+@条件+')=1

,@纵轴out,@横轴out

--生成交叉表处理语句 ,N'@纵轴sysname out,@横轴 sysnameout'

set@s='
set@s=''''
select@s=@s+'',[''+cast(['+@横轴+']as varchar)+'']=sum(case ['+@横轴
+']when ''''''+cast(['+@横轴+']as varchar)+'''''' then ['+@表体内容+']else 0 end)'' from ['+@TableName+']
'+@条件+'
groupby ['+@横轴+']'
execsp_executesql @s
,N'@svarchar(8000) out'
,@sqlout

--是否生成合计字段的处理
declare@sum1 varchar(200),@sum2 varchar(200),@sum3 varchar(200) select@sum1=case @是否加横向合计

when 1 then ',[合计]=sum(['+@表体内容+'])' else '' end



,@sum2=case @是否家纵向合计
when 1 then '['+@纵轴+']=case grouping(['


+@纵轴+']) when 1 then ''合计'' else cast(['





+@纵轴+']as varchar) end'
else'['+@纵轴+']'end
,@sum3=case@是否家纵向合计
when1 then ' with rollup'
else'' end

--生成交叉表
exec('select'+@sum2+@sql+@sum1+'
from['+@TableName+']
'+@条件+'
groupby ['+@纵轴+']'+@sum3)
go





因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务