行列互换

---psydbnew (PSYP_Trends_GetTestStressorAvgPoint)
SELECT QuestionNum,
     sum(case when BatchClassName=‘第一批‘ then AvgPoint else 0 end )as ‘第一批‘,
     sum(case when BatchClassName=‘第二批‘ then AvgPoint else 0 end )as ‘第二批‘,
     sum(case when BatchClassName=‘第三批‘ then AvgPoint else 0 end )as ‘第三批‘,
     sum(case when BatchClassName=‘第四批‘ then AvgPoint else 0 end )as ‘第四批‘
    FROM ( 
        select distinct a.TestID,b.QuestionNum,b.QuestionContent,c.TotalPoint,    
       (1.*c.TotalPoint/@TotalCount)as AvgPoint, @TotalCount as TotalCount,    
       cbc.BatchClassID,c.BatchClassID AS tmpBatchClassID,cbc.BatchClassName,
       cbc.BeginDate,cbc.EndDate  
      from V_R_Reports as a     
        left outer join PSY_T_QuestionBase as b on a.TestID=b.TestID     
        left outer join #tb as c on b.TestID=c.TestID AND b.QuestionNum=c.QuestionNum    
        left outer join PSY_U_CardBatchClass as cbc on a.UnitID=cbc.UnitID AND a.BatchClassID=cbc.BatchClassID    
        where a.UnitID=ltrim(rtrim(@UnitID)) and a.TestID=ltrim(rtrim(@TestID))    
           and a.BatchClassID in (Select Distinct BatchClassID FROM #tb_transition)  
           AND a.StaID in (Select Distinct StaID FROM #tb_transition)  
           AND a.DepartmentID in (Select Distinct DepartmentID FROM #tb_transition) 
           AND a.AreaID in (Select Distinct AreaID FROM #tb_transition) 
           AND a.Sex in (Select Distinct Sex FROM #tb_transition)     
           and a.Aid in (Select Distinct AgeID FROM #tb_transition))as tbs
    GROUP BY QuestionNum
---psydbnew (PSYP_Trends_GetTestStressorAvgPoint)
--------分列拆分结果
有表tb, 如下:
id          value
----------- -----------
1           aa,bb
2           aaa,bbb,ccc
欲按id,分拆value列, 分拆后结果如下:
id          value
----------- --------
1           aa
1           bb
2           aaa
2           bbb
2           ccc

--1. 旧的解决方法(sql server 2000)

create table tb(id int,value varchar(30))
insert into tb values(1,‘aa,bb‘)
insert into tb values(2,‘aaa,bbb,ccc‘)
Go

--方法1.使用临时表完成
SELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO # FROM syscolumns a, syscolumns b

SELECT A.id, value = SUBSTRING(A.[value], B.id, CHARINDEX(‘,‘, A.[value] + ‘,‘, B.id) - B.id)
FROM tb A, # B
WHERE SUBSTRING(‘,‘ + A.[value], B.id, 1) = ‘,‘

DROP TABLE #

--方法2.如果数据量小,可不使用临时表
select a.id , value = substring(a.value , b.number , charindex(‘,‘ , a.value + ‘,‘ , b.number) - b.number) 
from tb a join master..spt_values  b 
on b.type=‘p‘ and b.number between 1 and len(a.value)
where substring(‘,‘ + a.value , b.number , 1) = ‘,‘

--2. 新的解决方法(sql server 2005)
create table tb(id int,value varchar(30))
insert into tb values(1,‘aa,bb‘)
insert into tb values(2,‘aaa,bbb,ccc‘)
go

--方法1.使用xml完成
SELECT A.id, B.value FROM
(
  SELECT id, [value] = CONVERT(xml,‘<root><v>‘ + REPLACE([value], ‘,‘, ‘</v><v>‘) + ‘</v></root>‘) FROM tb
) A OUTER APPLY
(
  SELECT value = N.v.value(‘.‘, ‘varchar(100)‘) FROM A.[value].nodes(‘/root/v‘) N(v)
) B

--方法2.使用CTE完成
;with tt as 
(select id,[value]=cast(left([value],charindex(‘,‘,[value]+‘,‘)-1) as nvarchar(100)),Split=cast(stuff([value]+‘,‘,1,charindex(‘,‘,[value]+‘,‘),‘‘) as nvarchar(100)) from tb
union all
select id,[value]=cast(left(Split,charindex(‘,‘,Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(‘,‘,Split),‘‘) as nvarchar(100)) from tt where split>‘‘
)
select id,[value] from tt order by id option (MAXRECURSION 0)

DROP TABLE tb

----------列转行(列是动态的)
create table tb (cp varchar(3),xm01 int,xm02 int,xm03 int,xm04 int)
insert into tb
select ‘cp1‘,100,200,300,400 union all
select ‘cp2‘,10,20,30,40 union all
select ‘cp3‘,11,22,32,42 union all
select ‘cp4‘,112,222,321,422
---方法1
select * from tb
select cp,xm,sl from tb
unpivot
(sl for xm in(xm01,xm02,xm03,xm04)
)t
----方法2
declare @sql varchar(8000)
select @sql = isnull(@sql + ‘ union all ‘ , ‘‘ ) + ‘ select cp , [xm] = ‘ + quotename(Name , ‘‘‘‘) + ‘ , [s1] = ‘ + quotename(Name) + ‘ from tb‘
from syscolumns 
where name! = N‘cp‘ and ID = object_id(‘tb‘) --表名tb,不包含列名为cp的其它列
order by colid asc
exec(@sql + ‘ order by cp,xm ‘)

---列转行
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

----实现
declare @s nvarchar(4000)
select @s=isnull(@s+‘,‘,‘‘)+quotename(Name)
from syscolumns where ID=object_id(‘Class‘) and Name not in(‘Student‘) 
order by Colid
exec(‘select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in(‘[email protected]+‘))b‘)

go
select 
    Student,[Course],[Score] 
from 
    Class 
unpivot 
    ([Score] for [Course] in([数学],[物理],[英语],[语文]))b

----动态行转列
create table tb(Title nvarchar(20))
insert into tb values(N‘标题1‘)
insert into tb values(N‘标题2‘)
insert into tb values(N‘标题3‘)
insert into tb values(N‘标题4‘)
insert into tb values(N‘标题5‘)
go

declare @sql nvarchar(4000)
select @sql = isnull(@sql + ‘],[‘ , ‘‘) + Title from (select top 30 * from tb order by title) t group by Title
set @sql = ‘[‘ + @sql + ‘]‘
exec (‘select * from (select top 30 * from tb order by title) a pivot (max(Title) for Title in (‘ + @sql + ‘)) b‘)

drop table tb

/*--行列互换的通用存储过程(原著:邹建):将指定的表,按指定的字段进行行列互换*/
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 + ‘[email protected]‘ + @i + ‘+‘‘,[‘‘ + [‘ + @fdname + 
       ‘]+‘‘]=‘‘+cast([‘ + name + ‘] as varchar) from [‘ + @tbname + ‘]‘,
       @s4 = @s4 + ‘,@‘ + @i + ‘=‘‘select ‘‘[email protected]‘ + @i,
       @s5 = @s5 + ‘+‘‘ union all ‘‘[email protected]‘ + @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月
--------  ------   -------- -------- --------
奖金      300      310      320      330
工资      100      110      120      130
福利      200      210      220      230

(所影响的行数为 3 行)

时间: 2024-10-14 12:36:43

行列互换的相关文章

将二维数组中的行列互换

情景:二维数组可以存储表格数据,还可以根据下标索引加入各种运算,而且图片的关键运算方法也是以二维数组为基础进行矩阵运算的. //创建二维数组 int arr[][] = new int[][]{{1,2,3},{4,5,6},{7,8,9}}; System.out.println("行列互掉前:"); //输出二维数组 printArray(arr); int arr2[][] = new int[arr.length][arr.length]; //调整数组行列数据 for (in

java 二维数组行列互换

代码需求: 对等行等列的二维数组进行 行列 的互换 分析过程 主对角线是保持不变 行列互换即角标互换:[0][1] => [1][0] 循环次数:外层循环行,内层循环每一行的列 示意图 代码实现 public class ArrayReverse { public static void main(String[] args) { int arry[][] = new int[][] {{1,2,3},{4,5,6},{7,8,9}}; reverse(arry); printArray(arr

报表如何实现行列互换效果?

通常我们设计的二维的交叉报表,横向的维度和纵向的维度是固定的,而用户希望更希望能根据自己的需要快速转换横向纵向维度来查看报表. 如上图所示,我们通过点击一个按钮或文字,就可将报表的行列维度互相转换,这样的动态转换效果要怎么设置实现呢? 这里我介绍两种方法实现方法: 1. 两张报表超链接 2. 单张报表动态判断 两张报表超链接 实现思路: 二维的交叉报表行列维度有两种情况,我们只需对应两种情况做两张报表,切换的按钮用超链接实现,连接的目标就是另一张报表. 具体实现: 1. 新建一张报表,文件名为行

Oracle行列互换 横表和纵表

/* 在实际使用sql工作中总会碰到将某一列的值放到标题中显示.就是总说的行列转换或者互换. 比如有如下数据: ID NAME KECHENG CHENGJI -- ---------- -------------------- ------- 1 a 语文 80 2 a 数学 70 3 b 语文 40 4 b 数学 100 5 c 语文 90 6 c 数学 92 那末我要求显示的结果是: NAME YUWEN SHUXUE ---------- ---------------------- -

MS-SQLServer 2000 T-SQL 交叉报表(行列互换) 交叉查询 旋转查询

在MS-SQLServer 2005和oracle 中可以使用Pivot 和 Unpivot来做行列转换,不过不支持动态列哦. 在这里使用 case when then else end 语句,来实现行列转换. 如何实现动态列在最下面. 下面以学生成绩表来举例: id姓名 科目 成绩 1 张三 语文 602 张三 数学 653 张三 外语 704 李四 语文 805 李四 数学 906 李四 外语 857 王五 语文 708 王五 数学 719 王五 外语 7510 赵六 语文 6411 赵六 

MS SQLServer 交叉报表(行列互换)

在MS-SQLServer 2005 中可以使用pivot运算符来来实现行列转换. ,但在之前版本中必须使用 case when then else end 语句 下面以学生成绩表来举例: id姓名 科目 成绩 1 张三 语文 60 2 张三 数学 65 3 张三 外语 70 4 李四 语文 80 5 李四 数学 90 6 李四 外语 85 7 王五 语文 70 8 王五 数学 71 9 王五 外语 75 10 赵六 语文 64 11 赵六 数学 67 12 赵六 外语 76 查询后得出: 姓名

SQL行列互换很方便

---行转列--pivotcreate table tempTable( id int primary key identity(1,1), Student nvarchar(36), [Subject] nvarchar(36), Score int,) select * from tempTableinsert into tempTable values ('张三','语文','90')insert into tempTable values ('张三','语文','89')insert i

关于js算法行列互换

HTML代码的话就是 <ul id="ul1"></ul> css body,ul,li{margin: 0;padding: 0;font-family: "黑体";background: #eee;} li{list-style: none;} #ul1{margin: 20px auto;border-top: 1px solid #666;border-left: 1px solid #666;overflow: hidden;tex

sql行列互换

出现这个结果: sql如下: 1 SELECT y ,sum(case jidu when 1 then sales else 0 end) as yijidu,sum(case jidu when 2 then sales else 0 end) as erjidu from a GROUP BY y;