+ -
当前位置:首页 → 问答吧 → 關於行列轉換PIVOT的用法, 請教一下大嬸~~~

關於行列轉換PIVOT的用法, 請教一下大嬸~~~

时间:2011-12-12

来源:互联网

如下, 把表1轉換成表2該如何操作呢?

SQL code

表1

F1       F2       F3       F4       F5    
------------------------------------------  
2011     0.1      0.2      9.3      0.4
2012     1.1      6.2      1.3      1.4
2013     7.1      2.2      8.3      2.4
2014     3.1      3.2      3.3      3.4


把上面的表資料轉換成
表2


F1      2011      2012      2013      2014
------------------------------------------
F2       0.1      1.1       7.1       3.1 
F3       0.2      6.2       2.2       3.2 
F4       9.3      1.3       8.3       3.3 
F5       0.4      1.4       2.4       3.4


作者: icelovey   发布时间: 2011-12-12

百度,自己试不出来再发帖,直接发没意思啊

作者: geniuswjt   发布时间: 2011-12-12

改改列名和表名就行了
SQL code
--> --> (Roy)生成測試數據  
   
if not object_id('Class') is null  
    drop table Class  
Go  
Create table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语文] int)  
Insert Class  
select N'李四',77,85,65,65 union all  
select N'张三',87,90,82,78  
go  
  
declare @s nvarchar(4000),@s2 nvarchar(4000),@s3 nvarchar(4000),@s4 nvarchar(4000)  
select   
    @s=isnull(@s+',','declare ')+'@'+rtrim(Colid)+' nvarchar(4000)',  
    @s2=isnull(@s2+',','select ')+'@'+rtrim(Colid)+'='''+case when @s2 is not null then 'union all select' else ' select ' end+'  [科目]='''+quotename(Name,'''')+'''''',  
    @s3=isnull(@s3,'')+'select @'+rtrim(Colid)+'=@'+rtrim(Colid)+'+'',''+quotename([Student])+''=''+quotename('+quotename(Name)+','''''''')  from Class ',  
    @s4=isnull(@s4+'+','')+'@'+rtrim(Colid)  
from   
    syscolumns   
where  
    id=object_id('Class') and Name not in('Student')  
--print @s+' '+@s2+' '+@s3+' exec('+@s4+')' 显示执行语句  
exec(@s+' '+@s2+' '+@s3+' exec('+@s4+')')  
  
/*  
科目   李四   张三  
---- ---- ----  
数学   77   87  
物理   85   90  
英语   65   82  
语文   65   78  
*/  
  

來自:http://blog.csdn.net/roy_88/article/details/2715856

作者: roy_88   发布时间: 2011-12-12

SQL code
--------------------------------------------------------------------------
/*
数据库中tb表格如下
 
月份    工资   福利  奖金
1月     100    200   300
2月     110    210   310
3月     120    220   320
4月     130    230   330

我想得到的结果是

项目   1月    2月  3月  4月
工资   100    110  120  130
福利   200    210  220  230
奖金   300    310  320  330

就是说完全把表格的行列颠倒,有点像那种旋转矩阵,请问如何用sql 语句实现?
*/

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
/*--行列互换的通用存储过程(原著:邹建):将指定的表,按指定的字段进行行列互换*/

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 + '+'',['' + [' + @fdname + 
       ']+'']=''+cast([' + name + '] as varchar) 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

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

--用上面的存储过程测试:

create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
insert Test 
select '1月',100,200,300 union all
select '2月',110,210,310 union all
select '3月',120,220,320 union all
select '4月',130,230,330
go

exec p_zj 'Test', '月份' , '项目'

drop table Test
drop proc p_zj

/*
项目   1月         2月         3月         4月          
---- ----------- ----------- ----------- ----------- 
福利   200         210         220         230
工资   100         110         120         130
奖金   300         310         320         330

(所影响的行数为 3 行)
*/

/*
静态写法(SQL2005)
*/
--测试环境
create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
insert Test
select '1月',100,200,300 union all
select '2月',110,210,310 union all
select '3月',120,220,320 union all
select '4月',130,230,330
go
--测试语句
SELECT * FROM 
(
  SELECT 考核月份,月份,金额 FROM 
     (SELECT 月份, 工资, 福利, 奖金 FROM Test) p
  UNPIVOT
     (金额 FOR 考核月份 IN (工资, 福利, 奖金))AS unpvt
) T
PIVOT
(MAX(金额)  FOR 月份 in ([1月],[2月],[3月],[4月]))AS pt

--测试结果

/*
考核月份  1月     2月      3月     4月
-------  -----  -----   ------  -------
福利200210220230
工资100110120130
奖金300310320330
*/

--删除环境
Drop table Test

作者: fredrickhu   发布时间: 2011-12-12

SQL code
use Tempdb
go
--> --> 
 
if not object_id(N'T1') is null
    drop table T1
Go
Create table T1([F1] int,[F2] decimal(18,1),[F3] decimal(18,1),[F4] decimal(18,1),[F5] decimal(18,1))
Insert T1
select '2011',0.1,0.2,9.3,0.4 union all
select '2012',1.1,6.2,1.3,1.4 union all
select '2013',7.1,2.2,8.3,2.4 union all
select '2014',3.1,3.2,3.3,3.4
Go

declare @s nvarchar(4000),@s2 nvarchar(4000),@s3 nvarchar(4000),@s4 nvarchar(4000)  
select   
    @s=isnull(@s+',','declare ')+'@'+rtrim(Colid)+' nvarchar(4000)',  
    @s2=isnull(@s2+',','select ')+'@'+rtrim(Colid)+'='''+case when @s2 is not null then 'union all select' else ' select ' end+'  [F1]='''+quotename(Name,'''')+'''''',  
    @s3=isnull(@s3,'')+'select @'+rtrim(Colid)+'=@'+rtrim(Colid)+'+'',''+quotename([F1])+''=''+quotename('+quotename(Name)+','''''''')  from T1 ',  
    @s4=isnull(@s4+'+','')+'@'+rtrim(Colid)  
from   
    syscolumns   
where  
    id=object_id('T1') and Name not in('F1')  
--print @s+' '+@s2+' '+@s3+' exec('+@s4+')' 显示执行语句  
exec(@s+' '+@s2+' '+@s3+' exec('+@s4+')')  
  
/*  
F1    2011    2012    2013    2014
F2    0.1    1.1    7.1    3.1
F3    0.2    6.2    2.2    3.2
F4    9.3    1.3    8.3    3.3
F5    0.4    1.4    2.4    3.4
*/  
  

作者: roy_88   发布时间: 2011-12-12

SQL裡面有簡單點的辦法麼?

作者: icelovey   发布时间: 2011-12-12

用pivot的方法,
SQL code

create table 表1
(F1 int, F2 numeric(2,1), F3 numeric(2,1), F4 numeric(2,1), F5 numeric(2,1))

insert into 表1
select 2011, 0.1,  0.2,  9.3,  0.4 union all
select 2012, 1.1,  6.2,  1.3,  1.4 union all
select 2013, 7.1,  2.2,  8.3,  2.4 union all
select 2014, 3.1,  3.2,  3.3,  3.4
 

with c as
(select f1,ff,f
from 表1 a
unpivot 
(f for ff IN (F2,F3,F4,F5)) b)
select ff F1,[2011], [2012], [2013], [2014]
from c
pivot(max(f) for f1 in ([2011], [2012], [2013], [2014])) d

F1 [2011] [2012] [2013] [2014]
-----------------------------------
F2   0.1    1.1    7.1    3.1
F3   0.2    6.2    2.2    3.2
F4   9.3    1.3    8.3    3.3
F5   0.4    1.4    2.4    3.4

作者: ap0405140   发布时间: 2011-12-12