面试的时候遇到的数据库sql问题,没写过,然后研究了一下,现将结果记录下来,方便以后查询。 题目1:将表tbltest1的行列互换 表结构: student kemu fenshu student1 语文 80 student1 数学 90 student1 英语 85 student2 语文 85 student2 数学 92 student
面试的时候遇到的数据库sql问题,没写过,然后研究了一下,现将结果记录下来,方便以后查询。
题目1:将表tbltest1的行列互换
表结构:
student kemu fenshu
student1 语文 80
student1 数学 90
student1 英语 85
student2 语文 85
student2 数学 92
student2 英语 82
变成:
student 语文 数学 英语
student1 80 90 85
student2 85 92 82
sqlserver的sql语句:
declare @sql varchar(4000)
set @sql = 'select student'
select @sql = @sql + ',sum(case kemu when '''+ kemu +''' then fenshu else 0 end)['+ kemu+']'
from (select distinct kemu from tbltest1) as a
set @sql = @sql + ' from tbltest1 group by student'
exec(@sql)
或者
select student,sum(case kemu when '语文' then fenshu else 0 end) 语文,sum(case kemu when '数学' then fenshu else 0 end) 数学,sum(case kemu when '英语' then fenshu else 0 end) 英语 from tbltest group by student
注:个人觉得上面的好。如果一两个选项可以使用下面的sql,如果选项多上面的sql就显的方便的多。
2005的话好像还有个函数可以用,等研究好了再发上来。
题目2:合并
表结构tbltest2:
id strings
1 my
1 name
1 is
1 xudayu
2 hello
2 world
转化成:
id strings
1 my name is xudayu
2 hello world
sqlserver的sql语句:
--创建一个合并的函数
create function fliehebin(@id int)
returns varchar(5000)
as
begin
declare @str varchar(5000)
set @str=''
select @str=@str + cast(strings as varchar(50)) +' ' from tbltest2 where id=@id
set @str=substring(@str,1,len(@str))
return(@str)
end
go
--调用自定义函数得到结果
select distinct id,dbo.fliehebin(id) from tbltest2
=====================================================================
传说通用的, 如下:
if exists( select * from sysobjects where xtype='u'and name ='data2' ) begin drop table data2 end create table [data2] ( [人员编号] [varchar] (10) collate chinese_prc_ci_as not null , [基本工资] [numeric](18, 2) null , [奖金] [numeric](18, 2) null , [合计] [numeric](19, 2) null , constraint [pk_data2] primary key clustered ( [人员编号] ) on [primary] ) on [primary] go insert data2 select 'a1',1.00,11.00,111.00 insert data2 select 'a2',2.00,22.00,222.00 insert data2 select 'a3',3.00,33.00,333.00 insert data2 select 'a100',100.00,100.00,100.00 go drop procedure avb_initable go /* author:nyb time :2005/04/22 fixtime : aim :转置行和列 input :@tablenane 执行: execute avb_initable 'data2' */ create procedure avb_initable @tablenane varchar(128) as declare @string varchar(8000) --1 创建view if exists( select * from sysobjects where xtype='v'and name ='v_temp' ) begin drop view v_temp end select @string = ' create view v_temp as select * from ' + @tablenane execute (@string) if exists( select * from sysobjects where xtype='u'and name ='zztemp' ) begin drop table zztemp end declare @columnname varchar(200) declare @columnstr varchar(5000) select @columnstr= '' select @columnstr=@columnstr + quotename(rtrim(人员编号)) +'float null,' from v_temp print @columnstr set @columnstr = left(@columnstr,len(@columnstr)-1) select @string = 'create table zztemp (列名 varchar(50) null,' + @columnstr + ') on [primary]' print @string execute (@string) --2插入记录 declare column_cur scroll cursor for select name from syscolumns where id=object_id(@tablenane) and name '人员编号' open column_cur fetch first from column_cur into @columnname while (@@fetch_status-1) begin select @columnstr= '' if @columnname = '基本工资' select @columnstr= @columnstr + '''' + convert(varchar(20),isnull(基本工资,0)) + ''',' from v_temp else if @columnname = '奖金' select @columnstr= @columnstr + '''' + convert(varchar(20),isnull(奖金,0)) + ''',' from v_temp else if @columnname = '合计' select @columnstr= @columnstr + '''' + convert(varchar(20),isnull(合计,0)) + ''',' from v_temp set @columnstr = left(@columnstr,len(@columnstr)-1) select @string = 'insert into zztemp values(''' + @columnname + ''',' + @columnstr +')' execute(@string) fetch next from column_cur into @columnname end close column_cur deallocate column_cur go --察看结果 select * from data2 select * from zztemp
=====================================================================
if exists (select * from dbo.sysobjects where id = object_id(n'[dbo].[p_zj]') and objectproperty(id, n'isprocedure') = 1) drop procedure [dbo].[p_zj] go /*--行列互换的通用存储过程 将指定的表,按指定的字段进行行列互换 --邹建 2004.04--*/ /*--使用示例 --测试数据 create table 表(类别 varchar(10),男性 decimal(20,1),女性 decimal(20,1)) insert 表 select '小说',38.0,59.2 union all select '散文',18.9,30.6 union all select '哲学',16.2,10.2 /*--要求转换结果 性别 小说 散文 哲学 ---- ----- ----- ----- 男性 38.0 18.9 16.2 女性 59.2 30.6 10.2 (所影响的行数为 2 行) --*/ --调用存储过程 exec p_zj '表','类别','性别' --删除测试 drop table 表 --*/ create proc p_zj @tbname sysname, --要处理的表名 @fdname sysname, --做为转换的列名 @new_fdname sysname='' --为转换后的列指定列名 as declare @s1 varchar(8000),@s2 varchar(8000) ,@s3 varchar(8000),@s4 varchar(8000),@s5 varchar(8000) ,@i varchar(10) select @s1='',@s2='',@s3='',@s4='',@s5='',@i='0' select @s1=@s1+',@'+@i+' varchar(8000)' ,@s2=@s2+',@'+@i+'='''+case isnull(@new_fdname,'') when '' then '' else @new_fdname+'=' end+''''''+name+'''''''' ,@s3=@s3+' select @'+@i+'=@'+@i+'+'',[''+cast(['+@fdname+'] as varchar)+'']=''''''+replace(['+name+'],'''','''''''')+'''''''' from ['+@tbname+']' ,@s4=@s4+',@'+@i+'=''select ''+@'+@i ,@s5=@s5+'+'' union all ''+@'+@i ,@i=cast(@i as int)+1 from syscolumns where object_id(@tbname)=id and name@fdname order by colid select @s1=substring(@s1,2,8000) ,@s2=substring(@s2,2,8000) ,@s4=substring(@s4,2,8000) ,@s5=substring(@s5,16,8000) exec('declare '+@s1+' select '+@s2+@s3+' select '+@s4+' exec('+@s5+')') go
oracle's: