在做报表时,经常需要将数据表中的行转列,或者列转行,如果不知道方法,你会觉得通过SQL语句来实现非常难。这里,我将使用pivot和unpivot来实现看似复杂的功能。这个功能在sql2005及以上版本才有。

引用MSDN:
可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表。PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。UNPIVOT 与 PIVOT 执行相反的操作,将表值表达式的列转换为列值,但是在实际应用中,有些聚合之后的数据很难进行拆分。所以呢,unpivot并非pivot的逆过程。

pivot 提供的语法比一系列复杂的 SELECT...CASE 语句中所指定的语法更简单和更具可读性。
使用SELECT...CASE语句进行行转列的方法见:解析SQL Server中行转列问题

简单的例子如下:

---------行转列
--建表
create table test(编号 int,姓名 varchar(20),季度 int,销售额 int) 
insert into test values(1,'simon',1,1000)
insert into test values(1,'simon',2,2000)
insert into test values(1,'simon',3,3000)
insert into test values(1,'simon',4,4000)
insert into test values(2,'meme',1,5000)
insert into test values(2,'meme',2,6000)
insert into test values(2,'meme',3,7000)
insert into test values(2,'meme',4,8000)

--执行普通查询
select * from test

--执行转换查询
select 编号,姓名,
[1] as "一季度",
[2] as "二季度",
[3] as "三季度",
[4] as "四季度",
[5] as "随便1"
from
test
pivot
(
sum(销售额) 
for 季度 in
([1],[2],[3],[4],[5])
)
as pvt

--------列转行
--建表
create table test2(编号 int,姓名 varchar(20), 一季度 int, 二季度 int, 三季度 int, 四季度 int)
insert into test2 values(1,'simon',1000,2000,4000,5000)
insert into test2 values(2,'meme',3000,3500,4200,5500)

--执行普通查询
select * from test2

--执行转换查询
select 编号,姓名,季度,销售额
from
test2
unpivot
(
销售额
for 季度 in
(一季度,二季度,三季度,四季度)
) 
as unpvt

建议:如果你想了解的更加清楚,请参考:http://technet.microsoft.com/zh-cn/library/ms177410.aspx
注意:对升级到 SQL Server 2005 或更高版本的数据库使用 PIVOT 和 UNPIVOT 时,必须将数据库的兼容级别设置为 90 或更高。

有的SQL Server 2005初始安装时,默认的兼容级别为“80”,这时我们需要将兼容级别进行设置,不然,PIVOT不能正常的执行。我在使用PIVOT时就遇到这样的问题。
具体的修改方案如下:

修改兼容级别步骤
1、连接到相应的 SQL Server 数据库引擎实例之后,在对象资源管理器中,单击服务器名称以展开服务器树。
2、展开“数据库”,然后根据数据库的不同,选择用户数据库,或展开“系统数据库”,再选择系统数据库。
3、右键单击数据库,再单击“属性”。
4、在“数据库属性”对话框中,单击“选项”,将会看到“兼容级别”列表框中。
5、若要更改兼容级别,请从列表中选择其他选项。
可用选项包括 SQL Server 2000 (80)、SQL Server 2005 (90) 或 SQL Server 2008 (100)。
具体的兼容级别之间的差异请参考:http://technet.microsoft.com/zh-cn/library/bb510680.aspx

SQL2005语句实现行转列,列转行的更多相关文章

  1. SQL Server 行转列,列转行。多行转成一列

    一.多行转成一列(并以","隔开) 表名:A 表数据: 想要的查询结果: 查询语句: SELECT name , value = ( STUFF(( SELECT ',' + va ...

  2. Sql server 中将数据行转列列转行(二)

    老规矩,先弄一波测试数据,数据填充代码没有什么意义,先折叠起来: /* 第一步:创建临时表结构 */ CREATE TABLE #Student --创建临时表 ( StuName ), --学生名称 ...

  3. 在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列)

    原文:在论坛中出现的比较难的sql问题:15(生成动态删除列语句 分组内多行转为多列) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 1.如果去掉这个临时表中合计为0 ...

  4. sql语句实现行转列的3种方法实例

    sql语句实现行转列的3种方法实例 一般在做数据统计的时候会用到行转列,假如要统计学生的成绩,数据库里查询出来的会是这样的,但这并不能达到想要的效果,所以要在查询的时候做一下处理,下面话不多说了,来一 ...

  5. oracle 多行转多列查询

     oracle 多行转多列查询  ---create table Fruit(id int,name varchar(20), Q1 int, Q2 int, Q3 int, Q4 int);inse ...

  6. 如何获取ResultSet的行数和列数

    当我们执行数据库查询返回一个ResultSet的时候,很多情况下我们需要知道这个ResultSet的大小,即它的行数和列数.我们知道它的列数可以通过resultSet.getMetaData().ge ...

  7. Oracle 多行变一列的方法

    多行变一列的方法有很多,觉得这个第一眼看懂了当时就用的这个办法. 情况是这样的.以下数据前几列是一样的,需要把VAT_VALUE_CHAR 的值放在同一行上. SELECT * FROM ps_vat ...

  8. 有结果集的mysqli函数获取行数和列数

    <?php $mysqli=new mysqli("localhost", "root", "123456", "xsphp ...

  9. Oracle字符串行拆分成列的三种方式

    Oracle字符串行拆分成列的三种方式 --muphy 开发过程中经常会遇到将前台多个值用逗号连接一同传递到后台查询,这个用逗号连接的字符串分隔的每个字符串分别对应Oracle数据库表的不同行. 如下 ...

随机推荐

  1. 2016-12-21(1)Git常用命令总结

    友情链接:http://www.cnblogs.com/mengdd/p/4153773.html

  2. linux中模块的构建,传参,和printk函数的简单使用

    静态编译,动态加载应用想访问内核需要通过系统调用 驱动:1.模块(打包,加入内核)2.内核机制3.操作硬件 在Kconfig里面配置menuconfig的时候,不同的类型会在图形化界面的终端显示不用的 ...

  3. Java的CLASSPATH,趁还没忘赶紧写点

    咳咳,睡眠不足加上年龄增长,真的赶脚记忆力不行啦. 接触Java以来,对于环境配置就是按照网上的教程,一路复制粘贴,也没啥想法; 最近决定啃啃ThinkInJava,没看两章就看到这CLASSPATH ...

  4. 判断是否存在哈密顿路--HDU 5424

    题意:给一张无向图,判断是否是哈密顿图. 哈密顿路:经过每个点有且仅有一次的一条通路. 方法:每次找度数最小的点作为起点,然后dfs整个图,看能遍历到的点的数目能否达到n. #include<i ...

  5. 如何在MATLAB R2010a 中使用Visual C++ 2010编译器

    安装补丁VS2012MEXSupport.zip http://www.mathworks.com/matlabcentral/answers/93013-how-can-i-use-microsof ...

  6. linux crontab定时任务调用CI框架PHP代码

    *****监控项目中使用*****: sudo crontab -u wangyan -e i 5,25,45 * * * * wget http://xxx.xxx.com/xxx/xx Esc : ...

  7. C#常用操作类库一(验证类)

    public class Validator    {        #region  验证输入字符串为数字        /// <summary>        /// 验证输入字符串 ...

  8. Linux覆盖率一点研究:获取覆盖率数据

     首先,当然哥不介意你鄙视我在网上找的资料研究! 白盒覆盖率是啥东东这个问题大家自己查百度啦!我也不太懂,就知道它不是个东西,就这样开始吧(MT一般是先摸四蹄呢还是先黑金币呢?这是个问题)! 首先:l ...

  9. 图片上传安全性问题,根据ContentType (MIME) 判断其实不准确、不安全

    图片上传常用的类型判断方法有这么几种---截取扩展名.获取文件ContentType (MIME) .读取byte来判断(这个什么叫法来着?).前两种都有安全问题.容易被上传不安全的文件,如木马什么的 ...

  10. 实现PageProcessor

    4.1 实现PageProcessor 这部分我们直接通过GithubRepoPageProcessor这个例子来介绍PageProcessor的编写方式.我将PageProcessor的定制分为三个 ...