`
kevin6216
  • 浏览: 18798 次
  • 性别: Icon_minigender_1
  • 来自: 浙江
文章分类
社区版块
存档分类
最新评论

sqlserver 行转列

阅读更多

---1、最简单的行转列 
 /*     
  
 问题:假设有张学生成绩表(tb)如下: 
 姓名 课程 分数 
 张三 语文 74 
 张三 数学 83 
 张三 物理 93 
 李四 语文 74 
 李四 数学 84 
 李四 物理 94 
  
  
 想变成(得到如下结果):  
 姓名 语文 数学 物理  
 李四 74   84   94 
 张三 74   83   93 
 */ 
 --测试用 
 IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb] 
 GO 
 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,指课程不止语文、数学、物理这三门课程。(以下同) 
 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,得到如下脚本 
 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 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') 
 --得到SQL SERVER 2005 静态SQL。 
 select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b 
  
 --查询结果 
 /* 
 姓名         数学          物理          语文           
 ---------- ----------- ----------- -----------  
 李四         84          94          74 
 张三         83          93          74 
  
 (所影响的行数为 2 行) 
 */ 
  
  
 --2 加合计 
 /* 
 问题:在上述结果的基础上加平均分,总分,得到如下结果: 
 姓名 语文 数学 物理 平均分 总分  
 ---- ---- ---- ---- ------ ---- 
 李四 74   84   94   84.00  252 
 张三 74   83   93   83.33  250 
 */ 
  
 --SQL SERVER 2000 静态SQL。 
 select 姓名 姓名, 
   max(case 课程 when '语文' then 分数 else 0 end) 语文, 
   max(case 课程 when '数学' then 分数 else 0 end) 数学, 
   max(case 课程 when '物理' then 分数 else 0 end) 物理, 
   cast(avg(分数*1.0) as decimal(18,2)) 平均分, 
   sum(分数) 总分 
 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 + ' , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名' 
 exec(@sql)  
  
 --SQL SERVER 2005 静态SQL。 
 select m.* , n.平均分 , n.总分 from 
 (select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b) m, 
 (select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n 
 where m.姓名 = n.姓名 
  
 --SQL SERVER 2005 动态SQL。 
 declare @sql varchar(8000) 
 select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程 
 exec ('select m.* , n.平均分 , n.总分 from 
 (select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m ,  
 (select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n 
 where m.姓名 = n.姓名') 
  
 其他实例 
  
 http://topic.csdn.net/u/20100708/18/55df5a90-27a7-4452-a69a-27f735539a1f.html?seed=24842417&r=66831902#r_66831902 
  
  
 --3、不同数据按照序号转为列,方法基本同 1 
  
 if object_id('tb1') is not null drop table tb1 
 go 
 CREATE table tb1 --数据表 
 ( 
 cpici varchar(10) not null, 
 cname varchar(10) not null, 
 cvalue int null  
 ) 
 --插入测试数据 
 INSERT INTO tb1 values('T501','x1',31) 
 INSERT INTO tb1 values('T501','x1',33) 
 INSERT INTO tb1 values('T501','x1',5) 
  
 INSERT INTO tb1 values('T502','x1',3) 
 INSERT INTO tb1 values('T502','x1',22) 
 INSERT INTO tb1 values('T502','x1',3) 
  
 INSERT INTO tb1 values('T503','x1',53) 
 INSERT INTO tb1 values('T503','x1',44) 
 INSERT INTO tb1 values('T503','x1',50) 
 INSERT INTO tb1 values('T503','x1',23) 
  
  
 --在sqlserver2000里需要用自增辅助 
 alter table tb1 add id int identity 
 go 
 declare @s varchar(8000) 
 set @s='select cpici ' 
 select @s=@s+',max(case when rn='+ltrim(rn)+' then cvalue end) as cvlue'+ltrim(rn) 
 from (select distinct rn from (select rn=(select count(1) from tb1 where cpici=t.cpici and id <=t.id) from tb1 t)a)t 
 set @s=@s+' from (select rn=(select count(1) from tb1 where cpici=t.cpici and id <=t.id),* from tb1 t 
 ) t group by cpici' 
  
 exec(@s) 
 go 
 alter table tb1 drop column id  
  
 --再2005就可以用row_number 
 declare @s varchar(8000) 
 set @s='select cpici ' 
 select @s=@s+',max(case when rn='+ltrim(rn)+' then cvalue end) as cvlue'+ltrim(rn) 
 from (select distinct rn from (select rn=row_number()over(partition by cpici order by getdate()) from tb1)a)t 
 set @s=@s+' from (select rn=row_number()over(partition by cpici order by getdate()),* from tb1 
 ) t group by cpici' 
  
 exec(@s) 
  
 ---结果 
 /* 
 cpici      cvlue1      cvlue2      cvlue3      cvlue4 
 ---------- ----------- ----------- ----------- ----------- 
 T501       31          33          5           NULL 
 T502       3           22          3           NULL 
 T503       53          44          50          23 
 警告: 聚合或其他 SET 操作消除了空值。 
  
 (3 行受影响) 
  
 */ 
  
  
 --测试用 
 IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb] 
 GO 
 create table tb(电话号码 varchar(15), 通话时长 int ,行业 varchar(10)) 
 insert tb 
 select '13883633601', 10 ,'餐饮' union all 
 select '18689704236', 20 ,'物流' union all 
 select '13883633601', 20 ,'物流' union all 
 select '13883633601', 20 ,'汽车' union all 
 select '18689704236', 20 ,'医疗' union all 
 select '18689704236', 20 ,'it' union all 
 select '18689704236', 20 ,'汽车' union all 
 select '13883633601', 50 ,'餐饮' 
 go 
  
 declare @sql varchar(8000) 
 set @sql='select 电话号码,sum(通话时长) 通话总和' 
 select @sql=@sql+',max(case when rowid='+ltrim(rowid)+' then 行业 else '''' end) as [行业'+ltrim(rowid)+']' 
 from (select distinct rowid from (select (select count(distinct 行业) from tb where 电话号码=t.电话号码 and 行业 <=t.行业) rowid 
 from tb t) a) b 
 set @sql=@sql+' from ( select * , (select count(distinct 行业) from tb where 电话号码=t.电话号码 and 行业 <=t.行业) rowid 
 from tb t ) t group by 电话号码' 
 exec(@sql) 
  
 --结果 
 /* 
  
 (所影响的行数为 8 行) 
  
 电话号码            通话总和        行业1        行业2        行业3        行业4         
 --------------- ----------- ---------- ---------- ---------- ----------  
 13883633601     100         餐饮         汽车         物流          
 18689704236     80          it         汽车         物流         医疗 
  
 (所影响的行数为 2 行) 
  
 */ 

分享到:
评论

相关推荐

    SqlServer行转列

    ### SqlServer行转列 #### 知识点一:什么是行转列? 在数据库操作中,行转列(Pivot)是一种将数据表中的行数据转换为列数据的技术。这种技术通常用于改变数据的结构,使得原始数据更适合进一步的数据分析或报告...

    SQL Server行转列使用

    T-SQL(Transact-SQL)是微软SQL Server所使用的扩展SQL语言,它提供了丰富的数据处理功能,包括行转列。在SQL Server中,有两种主要的方法可以实现这一转换: 1. 使用CASE语句: CASE语句是SQL中一个非常强大的...

    sqlserver 行转列,列转行

    列转行行转列

    sqlserver 实现 行转列 split 分割的函数

    sqlserver 实现 行转列 split 分割的函数,具体使用方法写有在文件里。

    sql server动态行转列.sql

    sqlserver 动态行专列 避免了数据列过多的时候大量的使用case when then...... 原数据 : UserName Subject Score Nick 语文 80 Nick 数学 90 Nick 英语 70 Nick 生物 85 Kent 语文 80 Kent 数学 90 Kent ...

    SqlServer行转列和列转行

    SqlServer如何进行行转列和列转行方法

    行转列sql_server

    sql server 用于行转列,省得各位去找语句,select to_char(wm_concat('''' || valuelabel || '''')) name from (select distinct t.valuelabel from structuredrecruit t) select * from (select t.uhid, t....

    SQL Server行转列的方法解析

    以下是对SQL Server行转列方法的详细解析。 首先,我们可以使用SQL Server的`PIVOT`操作来实现行转列。`PIVOT`操作是SQL Server 2005引入的一个新特性,它允许我们将某个列的值转换为列标题,同时将其他列的值根据...

    SQL行转列参考代码(sqlserver)

    在SQL Server中,"行转列"是一种常见的数据操作,它可以帮助我们把表格中的多行数据转换成一列,或者将某一列的数据转换为多列显示。这种技术在数据分析、报表制作以及信息展示中非常实用。本文将详细介绍SQL Server...

    SQL 行转列+动态获取列名

    SQL 行转列+动态获取列名 通用的动态获取列名

    sqlserver行变列

    ### SQL Server 行转列操作详解 在数据库管理和数据分析领域,有时我们需要将表格中的行转换成列,这种操作称为“行转列”。行转列在实际应用中非常常见,尤其是在处理具有多维度的数据集时。例如,从一个记录学生...

    SQL Server中行转列问题的终极解决

    在SQL Server数据库管理中,行转列是一种常见的数据操作需求,尤其在数据分析和报表生成时。本篇文章将深入探讨如何利用CASE语句解决这一问题,为你的数据处理提供高效的策略。 首先,我们要理解行转列的基本概念。...

    SQLServer行转列实现思路记录

    本文主要探讨了三种实现SQLServer行转列的方法:静态SQL、动态SQL以及CASE WHEN语句。 首先,我们来看静态SQL的实现方式。在面试题中,这种方法适用于已知列名的情况。通过PIVOT操作,我们可以将特定的列(如`Score...

    行转列sql实例

    行转列sql实例行转列sql实例行转列sql实例行转列sql实例行转列sql实例

    SQL---行转列 详细描述

    在SQL Server 2000中,由于缺乏直接支持行转列的内置函数或语句,通常需要通过动态SQL来实现。具体步骤如下: 1. **构建动态SQL语句**:首先,需要查询出所有需要被转换为列的值,并基于这些值构造动态SQL。 2. **...

    sql server 中行转列

    在 SQL Server 中,“行转列”(Pivot)是一种常用的数据处理方式,它能够将表格中的行数据转换为列数据,从而使得数据更加易于理解和分析。这种方式特别适用于将汇总数据进行重新组织的情况。 #### 二、描述:代码...

    sql行转列解决方案.

    标题与描述均提到“SQL行转列解决方案”,这主要指的是在SQL中将数据表中的行数据转换为列数据的一种操作技巧,通常应用于需要对多行数据进行汇总展示或数据分析的场景。这种转换对于数据报告、统计分析等业务需求至...

    Sql Server 2005 行转列的实现 (横排)

    在SQL Server 2005中,我们经常遇到这样的需求:需要将数据库中的多行数据转换为多列显示,这通常被称为“行转列”或“行列互换”。这种操作在数据分析、报表制作或者简化数据显示时非常有用。本文将详细讲解如何在...

    SQL Server将一列的多行内容拼接成一行的实现方法

    昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行,比如表中有两列数据 : 类别 名称 AAA 企业1 AAA 企业2 AAA 企业3 ...

Global site tag (gtag.js) - Google Analytics