日期:2014-05-17  浏览次数:20777 次

SQL动态交叉查询
declare @sql1 varchar(8000)

set @sql1 = 'select Name as ' + '姓名'

select @sql1 = @sql1 + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'

from (select distinct Subject from tb) as a

set @sql1 = @sql1 + ' , cast(avg(result*1.0) as decimal(18,2)) 平均分,sum(result) 总分from tb group by name'

exec(@sql1)

拿网上的一个例子吧 

我想了解下他是怎么把select distinct Subject from tb里的值都放到case上的 

还用能不能直接写sql语句 不要变量 要动态实现的 

谢谢
------解决方案--------------------
借用大版的例子:
--1、行互列
--> --> (Roy)生成測試數據
  
if not object_id('Class') is null
    drop table Class
Go
Create table Class([Student] nvarchar(2),[Course] nvarchar(2),[Score] int)
Insert Class
select N'张三',N'语文',78 union all
select N'张三',N'数学',87 union all
select N'张三',N'英语',82 union all
select N'张三',N'物理',90 union all
select N'李四',N'语文',65 union all
select N'李四',N'数学',77 union all
select N'李四',N'英语',65 union all
select N'李四',N'物理',85 
Go
--2000方法:
动态:
 
declare @s nvarchar(4000)
set @s=''
Select     @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+' then [Score] else 0 end)'
from Class group by [Course]
exec('select [Student]'+@s+' from Class group by [Student]')
 
 
生成静态:
 
select 
    [Student],
    [数学]=max(case when [Course]='数学' then [Score] else 0 end),
    [物理]=max(case when [Course]='物理' then [Score] else 0 end),
    [英语]=max(case when [Course]='英语' then [Score] else 0 end),
    [语文]=max(case when [Course]='语文' then [Score] else 0 end) 
from 
    Class 
group by [Student]
 
GO
这个例子中。由于我们不能确定course除了上面四个课程之后,还会有什么古灵精怪的课程名,所以用动态,如果你的系统中只有这四个,就可以用代码最后面的部分来写死
------解决方案--------------------
引用:
Quote: 引用:

你把exec改成print就知道最终结果了,你这个是为了处理一些不确定有多少行的数据时使用的,如果你能确定行数就那么多,直接写死case when就行了

就是说动态的话一定要定义变量了 如果我写死了科目增加或者减少了不就会影响到这个查询吗 

我现在要做一个类似功能的报表 可是他只能支持sql语句 我又不想把他写死了 望解决 谢谢


这个直接写一个存储过程就行,存储过程中,能写动态语句,变量的。