关于SQL SERVER的行列转换问题

jt_linalam 2010-01-16 05:03:35
我有一张这样的表
employ_id year_text month_text days money
1 2010 1 5# 10
1 2010 1 6# 10
1 2010 1 7# 10
1 2010 1 8# 10
1 2010 1 9# 10
1 2010 1 10# 10
2 2010 1 5# 10
2 2010 1 6# 10
3 2010 1 7# 10
4 2010 1 8# 10
5 2010 1 9# 10
2 2010 1 10# 10

如何得到这样的数据
employ_id 5# 6# 7# 8# 9# 10#

1 10 10 10 10 10 10
2 10 10 0 0 0 10
3 0 0 10 0 0 0
4 0 0 0 10 0 0
5 0 0 0 0 10 0
好像直接使用行列转换的方式不行呢


...全文
119 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
jt_linalam 2010-01-16
  • 打赏
  • 举报
回复
行了。谢谢
--小F-- 2010-01-16
  • 打赏
  • 举报
回复
----------------------------------------------------------------
-- Author :fredrickhu(小F,向高手学习)
-- Date :2010-01-16 17:11:17
-- Version:
-- Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86)
-- Nov 24 2008 13:01:59
-- Copyright (c) 1988-2005 Microsoft Corporation
-- Developer Edition on Windows NT 5.1 (Build 2600: Service Pack 3)
--
----------------------------------------------------------------
--> 测试数据:[tb]
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([employ_id] int,[year_text] int,[month_text] int,[days] varchar(3),[money] int)
insert [tb]
select 1,2010,1,'5#',10 union all
select 1,2010,1,'6#',10 union all
select 1,2010,1,'7#',10 union all
select 1,2010,1,'8#',10 union all
select 1,2010,1,'9#',10 union all
select 1,2010,1,'10#',10 union all
select 2,2010,1,'5#',10 union all
select 2,2010,1,'6#',10 union all
select 3,2010,1,'7#',10 union all
select 4,2010,1,'8#',10 union all
select 5,2010,1,'9#',10 union all
select 2,2010,1,'10#',10
--------------开始查询--------------------------

---动态
declare @sql varchar(8000)
set @sql = 'select employ_id '
select @sql = @sql + ' , sum(case days when ''' + days + ''' then money else 0 end) [' + days + ']'
from (select distinct days from tb) as a
set @sql = @sql + ' from tb group by employ_id'
exec(@sql)

--静态
select
employ_id ,
sum(case days when '10#' then money else 0 end) [10#] ,
sum(case days when '5#' then money else 0 end) [5#] ,
sum(case days when '6#' then money else 0 end) [6#] ,
sum(case days when '7#' then money else 0 end) [7#] ,
sum(case days when '8#' then money else 0 end) [8#] ,
sum(case days when '9#' then money else 0 end) [9#]
from
tb
group by
employ_id

----------------结果----------------------------
/* employ_id 10# 5# 6# 7# 8# 9#
----------- ----------- ----------- ----------- ----------- ----------- -----------
1 10 10 10 10 10 10
2 10 10 10 0 0 0
3 0 0 0 10 0 0
4 0 0 0 0 10 0
5 0 0 0 0 0 10

(5 行受影响)
*/
pt1314917 2010-01-16
  • 打赏
  • 举报
回复
--> 测试数据: [tb]
if object_id('[tb]') is not null drop table [tb]
create table [tb] (employ_id int,year_text int,month_text int,days varchar(3),money int)
insert into [tb]
select 1,2010,1,'5#',10 union all
select 1,2010,1,'6#',10 union all
select 1,2010,1,'7#',10 union all
select 1,2010,1,'8#',10 union all
select 1,2010,1,'9#',10 union all
select 1,2010,1,'10#',10 union all
select 2,2010,1,'5#',10 union all
select 2,2010,1,'6#',10 union all
select 3,2010,1,'7#',10 union all
select 4,2010,1,'8#',10 union all
select 5,2010,1,'9#',10 union all
select 2,2010,1,'10#',10



declare @sql varchar(8000)
set @sql='select employ_id'
select @sql=@sql+',['+days+']=sum(case days when '''+days+''' then money else 0 end)'
from (select distinct days from tb)a
set @sql=@sql+' from tb group by employ_id'
exec(@sql)

/*结果
employ_id 10# 5# 6# 7# 8# 9#
----------- ----------- ----------- ----------- ----------- ----------- -----------
1 10 10 10 10 10 10
2 10 10 10 0 0 0
3 0 0 0 10 0 0
4 0 0 0 0 10 0
5 0 0 0 0 0 10

*/
jt_linalam 2010-01-16
  • 打赏
  • 举报
回复
等我看看,谢谢
pt1314917 2010-01-16
  • 打赏
  • 举报
回复

declare @sql varchar(8000)
set @sql='select employ_id'
select @sql=@sql+',['+days+']=sum(case days when '''+days+''' then money else 0 end)'
from (select distinct days from 表名)a
set @sql=@sql+' from 表名 group by employ_id'
exec(@sql)
jt_linalam 2010-01-16
  • 打赏
  • 举报
回复
等我看看,谢谢
jt_linalam 2010-01-16
  • 打赏
  • 举报
回复
等我看看先,谢谢啊!
SQL77 2010-01-16
  • 打赏
  • 举报
回复
----------------------------------------------------------------
-- Author :SQL77(只为思齐老)
-- Date :2010-01-16 17:05:05
-- Version:
-- Microsoft SQL Server 2000 - 8.00.194 (Intel X86)
-- Aug 6 2000 00:57:48
-- Copyright (c) 1988-2000 Microsoft Corporation
-- Desktop Engine on Windows NT 5.1 (Build 2600: Service Pack 3)
--
----------------------------------------------------------------
--> 测试数据:#A
if object_id('tempdb.dbo.#A') is not null drop table #A
go
create table #A([employ_id] int,[year_text] int,[month_text] int,[days] varchar(3),[money] int)
insert #A
select 1,2010,1,'5#',10 union all
select 1,2010,1,'6#',10 union all
select 1,2010,1,'7#',10 union all
select 1,2010,1,'8#',10 union all
select 1,2010,1,'9#',10 union all
select 1,2010,1,'10#',10 union all
select 2,2010,1,'5#',10 union all
select 2,2010,1,'6#',10 union all
select 3,2010,1,'7#',10 union all
select 4,2010,1,'8#',10 union all
select 5,2010,1,'9#',10 union all
select 2,2010,1,'10#',10
--------------开始查询--------------------------
DECLARE @SQL VARCHAR(8000)

SET @SQL='SELECT employ_id'

SELECT @SQL=@SQL+',SUM(CASE WHEN days='''+LTRIM([days])+'#'' THEN money ELSE 0 END)AS '''+LTRIM(days)+'#'''

FROM
(SELECT DISTINCT TOP 100 PERCENT CONVERT(INT,REPLACE(days,'#',''))AS DAYS FROM #A
ORDER BY CONVERT(INT,REPLACE(days,'#',''))

)AS T
EXEC( @SQL+' FROM #A GROUP BY employ_id')

--select * from #A
----------------结果----------------------------
/*

(所影响的行数为 12 行)

employ_id 5# 6# 7# 8# 9# 10#
----------- ----------- ----------- ----------- ----------- ----------- -----------
1 10 10 10 10 10 10
2 10 10 0 0 0 10
3 0 0 10 0 0 0
4 0 0 0 10 0 0
5 0 0 0 0 10 0



*/
--小F-- 2010-01-16
  • 打赏
  • 举报
回复
*
标题:普通行列转换(version 2.0)
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:2008-03-09
地点:广东深圳
说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法。

问题:假设有张学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
想变成(得到如下结果):
姓名 语文 数学 物理
---- ---- ---- ----
李四 74 84 94
张三 74 83 93
-------------------
*/

create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
insert into tb values('张三' , '语文' , 74)
insert into tb values('张三' , '数学' , 83)
insert into tb values('张三' , '物理' , 93)
insert into tb values('李四' , '语文' , 74)
insert into tb values('李四' , '数学' , 84)
insert into tb values('李四' , '物理' , 94)
go

--SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)
select 姓名 as 姓名 ,
max(case 课程 when '语文' then 分数 else 0 end) 语文,
max(case 课程 when '数学' then 分数 else 0 end) 数学,
max(case 课程 when '物理' then 分数 else 0 end) 物理
from tb
group by 姓名

--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
declare @sql varchar(8000)
set @sql = 'select 姓名 '
select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
from (select distinct 课程 from tb) as a
set @sql = @sql + ' from tb group by 姓名'
exec(@sql)

--SQL SERVER 2005 静态SQL。
select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b

--SQL SERVER 2005 动态SQL。
declare @sql varchar(8000)
select @sql = isnull(@sql + '],[' , '') + 课程 from tb group by 课程
set @sql = '[' + @sql + ']'
exec ('select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b')

---------------------------------
jt_linalam 2010-01-16
  • 打赏
  • 举报
回复
可否详细点呢?
SQL77 2010-01-16
  • 打赏
  • 举报
回复
----------------------------------------------------------------
-- Author :SQL77(只为思齐老)
-- Date :2010-01-16 17:05:05
-- Version:
-- Microsoft SQL Server 2000 - 8.00.194 (Intel X86)
-- Aug 6 2000 00:57:48
-- Copyright (c) 1988-2000 Microsoft Corporation
-- Desktop Engine on Windows NT 5.1 (Build 2600: Service Pack 3)
--
----------------------------------------------------------------
--> 测试数据:#A
if object_id('tempdb.dbo.#A') is not null drop table #A
go
create table #A([employ_id] int,[year_text] int,[month_text] int,[days] varchar(3),[money] int)
insert #A
select 1,2010,1,'5#',10 union all
select 1,2010,1,'6#',10 union all
select 1,2010,1,'7#',10 union all
select 1,2010,1,'8#',10 union all
select 1,2010,1,'9#',10 union all
select 1,2010,1,'10#',10 union all
select 2,2010,1,'5#',10 union all
select 2,2010,1,'6#',10 union all
select 3,2010,1,'7#',10 union all
select 4,2010,1,'8#',10 union all
select 5,2010,1,'9#',10 union all
select 2,2010,1,'10#',10
--------------开始查询--------------------------
DECLARE @SQL VARCHAR(8000)
SET @SQL='SELECT employ_id'
SELECT @SQL=@SQL+',SUM(CASE WHEN days='''+[days]+''' THEN money ELSE 0 END)AS '''+days+''''
FROM (SELECT DISTINCT days FROM #A)AS T
EXEC( @SQL+' FROM #A GROUP BY employ_id')

--select * from #A
----------------结果----------------------------
/*

(所影响的行数为 12 行)

employ_id 10# 5# 6# 7# 8# 9#
----------- ----------- ----------- ----------- ----------- ----------- -----------
1 10 10 10 10 10 10
2 10 10 10 0 0 0
3 0 0 0 10 0 0
4 0 0 0 0 10 0
5 0 0 0 0 0 10


*/
SQL77 2010-01-16
  • 打赏
  • 举报
回复
动态行转列
本课程根据讲师十多年在世界500强外企的生产环境中的SQL Serer数据库管理和项目实施经验倾心打造。课程系统性强,知识体系完整,覆盖90%以上的企业环境下SQL Server高可用场景,课程中不仅演示详细的操作步骤,更加突出最常见的故障和问题,让学员少走“弯路”,不只是让学员学会“操作”更能让学员“操作”的规范,满满的干货分享,一些课程资料(架构图、部署规划表格等)不仅可以帮助学员掌握技能,也可以作为学员在企业生产环境中实施SQL Server高可用的配置文档、操作手册等。课程的实验环境介绍:1)全部基于微软域环境和企业版SQL Server AOAG - 95%以上的企业环境都是在域环境中,不介绍非域环境和标准版的SQL Server高可用性组,这的配置在企业中较罕见,没有实践意义,不浪费学员时间。2)相应域环境已提前部署和配置好 - 学员导入虚拟机即可开始实验,无需从零开始搭建域环境,所有实验中SQL Server均已加域,直入主题,节省大量时间。3)最新的Windows Server故障转移集群(WS2016、WS2019)和最新版本的SQL ServerSQL2017、SQL2019) -  WS2016-SQL2017与WS2019-SQL2019是目前大多数企业SQL Server高可用的主要平台,基于微软产品生命周期现在一些企业也在讲早期的AOAG向这两个版本迁移,掌握这两种组合不仅让学员学会,更能学有所用。本课程为后续SQL Server进阶课程铺垫,是通向SQL Server DBA 专家的必经之路,讲师每周答疑两次。所有课程资料包括:课程PPT、架构图、部署规划表格、各类脚本学员均可下载。     

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧