SQL2000行转列于列转行问题,急~~~ (部门是不确定几个的)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL2000行转列于列转行问题,急~~~ (部门是不确定几个的)相关的知识,希望对你有一定的参考价值。

静态脚本:
select '当月入职人数' as 项目
, case when 部门='行政部' then 当月入职人数 else null end as 行政部
, case when 部门='技术部' then 当月入职人数 else null end as 技术部
from 表名
union all
select '当月离职人数' as 项目
, case when 部门='行政部' then 当月离职人数 else null end as 行政部
, case when 部门='技术部' then 当月离职人数 else null end as 技术部
from 表名
union all
select '当月在职人数' as 项目
, case when 部门='行政部' then 当月在职人数 else null end as 行政部
, case when 部门='技术部' then 当月在职人数 else null end as 技术部
from 表名

改动态脚本(只改部门,即改原表行不定,列数目固定):
declare @sql nvarchar(4000)
set @sql=''
set @sql=@sql+'
select ''当月入职人数'' as 项目
'
select @sql=@sql+', case when 部门='''+部门+''' then 当月入职人数 else null end as '+部门
from 表名
set @sql=@sql+'
from 表名
'
set @sql=@sql+'union all
select ''当月离职人数'' as 项目
'
select @sql=@sql+', case when 部门='''+部门+''' then 当月离职人数 else null end as '+部门
from 表名
set @sql=@sql+'
from 表名
'
set @sql=@sql+'union all
select ''当月在职人数'' as 项目
'
select @sql=@sql+', case when 部门='''+部门+''' then 当月在职人数 else null end as '+部门
from 表名
set @sql=@sql+'
from 表名
'
exec sp_executesql @sql

改动态脚本(改原表行和列数目不固定,两层动态脚本,能实现但基本难读):
declare @sql nvarchar(4000)
set @sql='declare @sql_in nvarchar(4000)
set @sql_in='' '' '
set @sql=@sql+'select @sql_in=@sql_in+''union all
select ''''''+name+'''''' as 项目
'
select @sql=@sql+', case when 部门='''''+部门+''''' then ''+name+'' else null end as '+部门
from 表名
set @sql=@sql+'
from 表名
''
from syscolumns where id=(select id from sysobjects where name=''表名'')
order by colorder
set @sql_in=stuff(@sql_in,1,10,'''')
exec sp_executesql @sql_in
'
exec sp_executesql @sql

由于是sql2000,nvarchar类型只能最多4000个字,如果你部门太多,动态脚本长度肯定是不行的
参考技术A 你看下边的例子:
use test
go
if object_id('test.dbo.tb') is not null drop table tb
-- 创建数据表
create table tb
(
EmpNo varchar(2),
MotionNo varchar(6),
RecNo char(7),
Qty1 int,
Qty2 int
)
go
--插入测试数据
insert into tb select 'A','00000','Rec001',11,88
union all select 'A','00001','Rec001',20,55
union all select 'B','00000','Rec001',8,66
union all select 'C','00000','Rec001',10,23
union all select 'C','00001','Rec001',15,120
union all select 'A','00000','Rec002',16,231
union all select 'A','00001','Rec002',22,112
union all select 'B','00001','Rec002',30,121
union all select 'C','00003','Rec003',32,55
go
--代码实现

declare @sql nvarchar(max)
select @sql=isnull(@sql+',','')+'Qty'+ltrim(num)+'1=max(case when RecNo='''+rtrim(RecNo)+''' then rtrim(Qty1) end)'
+',Qty'+ltrim(num)+'2=max(case when RecNo='''+rtrim(RecNo)+''' then rtrim(Qty2) end)'
+',RecNo'+ltrim(num)+'=max(case when RecNo='''+rtrim(RecNo)+''' then RecNo end)'
from (select distinct RecNo,num=row_number()over(order by getdate()) from tb group by RecNo)t
exec('select EmpNo,MotionNo,'+@sql+' from tb group by EmpNo,MotionNo order by EmpNo')

/*测试结果

EmpNo MotionNo Qty11 Qty12 RecNo1 Qty21 Qty22 RecNo2 Qty31 Qty32 RecNo3
---------------------------------------------------------------------------------
A 00000 11 88 Rec001 16 231 Rec002 NULL NULL NULL
A 00001 20 55 Rec001 22 112 Rec002 NULL NULL NULL
B 00000 8 66 Rec001 NULL NULL NULL NULL NULL NULL
B 00001 NULL NULL NULL 30 121 Rec002 NULL NULL NULL
C 00000 10 23 Rec001 NULL NULL NULL NULL NULL NULL
C 00001 15 120 Rec001 NULL NULL NULL NULL NULL NULL
C 00003 NULL NULL NULL NULL NULL NULL 32 55 Rec003

(7 行受影响)
*/追问

你这是行转列... 我现在需要的是行转列,列转成行...
还有一点我需要的是2000的语法...

追答

例如:如题:例如我有一个表tb_A(编号,姓名,学科,分数)
记录如下:
001 小李 数学 100
001 小李 语文 88
001 小李 英语 99
002 小张 数学 60
002 小张 语文 60
002 小张 英语 60
按照你的方法显示的结果是:
字段名: 编号 姓名 数学 语文 英语 数学 语文 英语
001 小李 100 88 99 100 88 99
001 小张 60 60 60 60 60 60
我想要的现实结果是:
字段名: 编号 姓名 数学 语文 英语
001 小李 100 88 99
001 小张 60 60 60
怎样实现?

解决:

IF NOT OBJECT_ID('成绩表') IS NULL
DROP TABLE 成绩表
GO

CREATE TABLE [成绩表] (
[编号] NVARCHAR(10),
[姓名] NVARCHAR(10),
[学科] NVARCHAR(10),
[分数] INT)
GO

INSERT INTO [成绩表]
SELECT N'001',N'小李',N'数学',100 UNION
SELECT N'001',N'小李',N'语文',88 UNION
SELECT N'001',N'小李',N'英语',99 UNION
SELECT N'002',N'小张',N'数学',60 UNION
SELECT N'002',N'小张',N'语文',60 UNION
SELECT N'002',N'小张',N'英语',60

DECLARE @Sql NVARCHAR(4000)
SET @Sql = ''
SELECT @Sql = @Sql + ',' + QUOTENAME([学科]) + '=MAX(CASE WHEN [学科]=' + QUOTENAME([学科], '''') + ' THEN [分数] ELSE 0 END)'
FROM 成绩表
GROUP BY [学科]

EXEC ('SELECT [编号], [姓名]' + @SQL + ' FROM [成绩表] GROUP BY [编号], [姓名]')

参考技术B 我是把数据都取出来 然后new一个DataTable 用部门做列名 然后把对应部门的值放到每一个单元格中 参考技术C step1,行转列
项目 部门1 部门2 部门3 。。。。
proj1 1 2 3
step2,
3个union all (3列的情况 )
列数也动态 那就再来一次动态拼 利用 syscolumns表

Oracle列转行,行转列

我现在的表如下:

产品名称 销售额 季度
奶酪 50 第一季度
奶酪 60 第二季度
啤酒 50 第二季度
啤酒 80 第四季度
。。。
。。。
想转换成如下格式
产品名称 第一季度销售额 第二季度销售额 第三季度销售额 第四季度销售额
奶酪 50 60 0 0
啤酒 0 50 0 80

请问该如何转换呢~产品名称的数据量很大,非常感激,Oracle的~

oracle下可以用函数decode处理:

select 产品名称,
sum(decode(季度,'第一季度',销售额,0)) 第一季度销售额,
sum(decode(季度,'第二季度',销售额,0)) 第二季度销售额,
sum(decode(季度,'第三季度',销售额,0)) 第三季度销售额,
sum(decode(季度,'第四季度',销售额,0)) 第四季度销售额,
from 表名
group by 产品名称;
参考技术A select 产品名称,sum(case when 季度='第一季度' then 销售额 else 0 end) as 第一季度销售额,
sum(case when 季度='第二季度' then 销售额 else 0 end) as 第二季度销售额,
sum(case when 季度='第三季度' then 销售额 else 0 end) as 第三季度销售额,
sum(case when 季度='第四季度' then 销售额 else 0 end) 第四季度销售额
from 表名 group by 产品名称;
参考技术B select 产品名称,
max(case when 季度=‘第一季度’then 销售额 else 0 end)as 第一季度销售额,
max(case when 季度=‘第二季度’then 销售额 else 0 end)as 第二季度销售额,
max(case when 季度=‘第三季度’then 销售额 else 0 end)as 第三季度销售额,
max(case when 季度=‘第四季度’then 销售额 else 0 end)as 第四季度销售额,
sum(销售额)as 总销售额 /////可可选可不选
from 表
group by 产品名称
having sum(销售额)>数值 /////可选可不选

以上是关于SQL2000行转列于列转行问题,急~~~ (部门是不确定几个的)的主要内容,如果未能解决你的问题,请参考以下文章

死磕:SQL行转列汇总(全网最全最详细)

MySQL行转列与列转行

Hive 行转列 & 列转行

SAS行转列&&列转行

重温SQL——行转列,列转行

sql的行转列(PIVOT)与列转行(UNPIVOT)