SQL server 动态行转列

在学习数据库的时候,遇到了怎么把数据表中的内容转变成数据表的字段,在此,记录一下自己对行转列的理解

比如有个学生成绩表:

stuid:学号

course:科目

score:成绩

表的内容为:

stuid  course  score

0101  语文      78

0101  数学      90

0101  英语      67

0101  物理      88

而我们想要的是类似下表:

stuid  语文  数学  英语  物理

0101   78  90   67    88

这个时候就需要用到行转列,行转列有动态静态之分:

静态行转列:通过sql语句,静态的进行转换,一旦原表的数据有改动,比如增加化学成绩,或者删除物理成绩,我们就得重新改变sql语句:

就上表,转换的sql语句为:

select stuid,
max(case course when ‘语文‘ then score else 0 end)语文,
max(case course when ‘数学‘ then score else 0 end)数学,
max(case course when ‘英语‘ then score else 0 end)英语,
max(case course when ‘物理‘ then score else 0 end)物理
from scores    --表名
 group by stuid  --分组查询

主要知识:max() ,case,group by 分组查询。

max()取最大值。

case:我的理解是从几个选项中选择,比如:

case course when ‘语文‘ then score else 0 end当course 为语文时,case返回对应的score与0当中的一个,在本例中,查询第一条数据:

0101  语文      78此时:course=‘语文’,score=78,则case返回78,当查询第二条数据的时候:0101  数学      90course=‘语文’不存在,则返回 0 (else 0 )以此类推得:
max(78,0,0,0),max()取最大值,最后的数据就是 78,

所谓静态,就是我们手动静态的获取每一个字段(语文,数学,英语,物理),一旦科目有所改变,我们就得修改sql语句,不怎么方便

而动态行转列就可以避免这种情况,它是动态的自己根据原表中的数据,获取字段名:

declare @sql varchar(8000) --申明一个变量 @sql,数据类型为 varchar(8000)
set @sql=‘select stuid,‘      -- 使用 set 为@sql 赋值
select @sql =@sql +‘max(case course when ‘‘‘+course +‘‘‘then score else 0 end)‘+‘‘‘‘course +‘‘‘,‘
from (select distinct course from scores) as sc           --使用select 为@sql赋值
set @sql =left(@sql,len(@sql)-1)+‘from scores group by stuid‘
exec(@sql)    --执行@sql

注意:在sql语句中,使用单引号 ’  来确定字符串的范围,如果字符串本身含有单引号如:‘  姓名:‘张三’,性别:‘男’  ’,这时候需要用 ‘‘ ,即两个单引号来表示字符串本身的单引号。

set 语句大家应该很熟悉,为变量赋值,而select 其实也可以看做一个赋值关键字,不过是一个循环赋值(个人理解)而已。

如 :select stuid from students,表示将students表中的所有stuid属性值(1,2,3,4......)赋值给变量stuid:

stuid=1,对stuid操作(如输出stuid=1)

stuid=2,对stuid操作(如输出stuid=2)

stuid=3,对stuid操作(如输出stuid=3)

stuid=4........

所以,上边的动态行转列中的select赋值语句可以理解为:

将from 后边的(select course from scores)所查询到的结果,逐一赋值给course变量,并且,每一次复制后的操作为:字符串连接

所以

select @sql [email protected] +‘max(case course when ‘‘‘+course +‘‘‘then score else 0 end)‘+‘‘‘‘course +‘‘‘,‘
from (select distinct course from scores)的执行过程为:@sql=‘select stuid,‘+‘max(case course when ‘‘‘+语文+‘‘‘then score else 0 end)‘+‘‘‘‘语文+‘‘‘,‘ [email protected]@[email protected]+‘max(case course when ‘‘‘+数学+‘‘‘then score else 0 end)‘+‘‘‘‘数学+‘‘‘,‘   [email protected]
@[email protected]+‘max(case course when ‘‘‘+英语+‘‘‘then score else 0 end)‘+‘‘‘‘英语+‘‘‘,‘   [email protected]
@[email protected]+‘max(case course when ‘‘‘+物理+‘‘‘then score else 0 end)‘+‘‘‘‘物理+‘‘‘,‘   [email protected]是不是和静态的代码很像?因为它们的原理都是一样的:max(),case,group by,不同的是动态行转列使用动态拼接字符串的方法,动态的从原表当中找出我们需要的字段,如果原表当中删除了物理成绩,我们就查不到物理成绩,自然也就不会将科目‘物理’加入到结果当中,如果原表增加了化学成绩,我们同样可以查到 化学成绩,并将其加入到结果当中,最后,通过exec语句执行@sql,这就是动态的行转列了。
 
 
时间: 2024-10-11 21:37:40

SQL server 动态行转列的相关文章

SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段

一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现代码(SQL Codes) 方法一:使用拼接SQL,静态列字段: 方法二:使用拼接SQL,动态列字段: 方法三:使用PIVOT关系运算符,静态列字段: 方法四:使用PIVOT关系运算符,动态列字段: 扩展阅读一:参数化表名.分组列.行转列字段.字段值: 扩展阅读二:在前面的基础上加入条件过滤: 参考文献(References) 二.背景(Contexts) 其实行转列并不是一个什么新鲜的

SQL Server 动态行转列(轉載)

一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现代码(SQL Codes) 方法一:使用拼接SQL,静态列字段; 方法二:使用拼接SQL,动态列字段; 方法三:使用PIVOT关系运算符,静态列字段; 方法四:使用PIVOT关系运算符,动态列字段; 二.背景(Contexts) 其实行转列并不是一个什么新鲜的话题了,甚至已经被大家说到烂了,网上的很多例子多多少少都有些问题,所以我希望能让大家快速的看到执行的效果,所以在动态列的基础上再把

代码实现SQL Server动态行转列,不用存储过程

分两步查询,第一步查询出动态列,第二步使用PIVOT函数. 代码: List<DataTable> dataTableList = new List<DataTable>(); #region 指标 DataTable dtEvaItemTitle = db.RunTable<Edu_EvaluationRecord>(string.Format(@" select distinct eva.id, eva.name from Edu_EvaluationRe

转:SQL Server 动态行转列

http://www.cnblogs.com/gaizai/p/3753296.html http://www.cnblogs.com/maanshancss/archive/2013/03/13/2957108.html

SQL SERVER特殊行转列案列一则

原文:SQL SERVER特殊行转列案列一则 今天有个同事找我,他说他有个需求,需要进行行转列,但是又跟一般的行转列有些区别,具体需求如下所说,需要将表1的数据转换为表2的显示格式. 我想了一下,给出了一个解决方法,具体如下所示(先给出测试数据) INSERT INTO TEST SELECT 1,    1,    '定型名称',    '预定型'           UNION ALL SELECT 1,    2,    '进布方式',    '调平'             UNION 

通过sql实现动态行转列

上一章我们讲了固定行转列,本章我们就将一下怎么动态实现行转列的.因为有时候需要行专列的值有成千上万条,不可能再用固定行转列的方法,否则你一定会崩溃掉的.好了,废话不多说,开始吧!常见一张表tmp_test,内容如下: 实现代码:create or replace procedure p_test isv_sql varchar2(2000); cursor cursor_1 isselect distinct subject from tmp_test order by subject; beg

SQL SERVER PIVOT 行转列、列传行

在数据库操作中,有些时候我们遇到需要实现"行转列"的需求,例如一下的表为某店铺的一周收入情况表: WEEK_INCOME(WEEK VARCHAR(10),INCOME DECIMAL) 我们先插入一些模拟数据: INSERT INTO WEEK_INCOME SELECT '星期一',1000 UNION ALL SELECT '星期二',2000 UNION ALL SELECT '星期三',3000 UNION ALL SELECT '星期四',4000 UNION ALL SE

sql server 2012 行转列

table_source PIVOT( 聚合函数(value_column) FOR pivot_column IN(<column_list>) ) 对于一个字段的汇总和转置,只用一次. ) tb pivot(max(copies) for ORDER_TYPE in ([11],[12],[13],[14])) tb 对于多个字段的汇总和转置,要嵌套多次. ) tb pivot(max(copies) for ORDER_TYPE in ([11],[12],[13],[14])) tb

动态行转列 pivot实现

declare @sql varchar(8000)    begin              set @sql=''  --初始化变量@sql              select  @[email protected]+',['+ convert(varchar(10),CreateDate,120)+']' from  vwStationYield               where CreateDate > DATEADD(dd,-14,convert(varchar(10),g