sql行列旋转
一,行转列
先建立测试数据

if OBJECT_ID('week_income') is not null
drop table week_income
go
create table week_income
(
employee varchar(10),
weekname varchar(10),
income int
)
go
insert into week_income
select '張三','星期一',1000 union all
select '張三','星期二',2000 union all
select '張三','星期三',1500 union all
select '張三','星期四',2000 union all
select '張三','星期五',3000 union all
select '張三','星期六',4000 union all
select '張三','星期日',5000 union all
select '李四','星期一',1000 union all
select '李四','星期二',2000 union all
select '李四','星期三',1500 union all
select '李四','星期四',2000 union all
select '李四','星期五',3000 union all
select '李四','星期六',4000 union all
select '李四','星期日',8000 select * from week_income

1.1 用传统的case when 语法实现行转列。

select employee as '社員'
,sum(case weekname when '星期一' then income else 0 end) as '星期一'
,sum(case weekname when '星期二' then income else 0 end) as '星期二'
,sum(case weekname when '星期三' then income else 0 end) as '星期三'
,sum(case weekname when '星期四' then income else 0 end) as '星期四'
,sum(case weekname when '星期五' then income else 0 end) as '星期五'
,sum(case weekname when '星期六' then income else 0 end) as '星期六'
,sum(case weekname when '星期日' then income else 0 end) as '星期日'
from week_income
group by employee

1.2 用sqlserver2005以后新增加的pivot语法实现行转列。
pivot的语法如下:

SELECT <non-pivoted column>,
[first pivoted column] AS <column name>,
[second pivoted column] AS <column name>,
...
[last pivoted column] AS <column name>
FROM
(<SELECT query that produces the data>)
AS <alias for the source query>
PIVOT
(
<aggregation function>(<column being aggregated>)
FOR
[<column that contains the values that will become column headers>]
IN ( [first pivoted column], [second pivoted column],
... [last pivoted column])
) AS <alias for the pivot table>
<optional ORDER BY clause>;


select employee as '社員',[星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日] --step 3
from (select employee ,weekname,income from week_income) t -- step 2
pivot
(
--step 1
sum(income) for weekname in([星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日])
) b

pivot分为3个步骤:
1,进行行列转换
sum(income) for weekname in([星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日])
注意:聚合函数sum等是决定重复行数据的处理方法,比如有两个星期一,就把这两个值合并了。
2,定义检索数据源(select employee ,weekname,income from week_income) t
注意别名t不能省略。这里要特别注意employee这一列并没有在步骤1中出现,sqlserver会默认按employee进行分组,这个功能挺棒的。
3,选择结果集中的列,全部选择可以用*。
employee as '社員',[星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日]
注意:可以对列名取别名,也可以只检索其中的部分列,而不必全部检索出所有列。
转换结果
二,列转行
以上面的转换结果作为数据表,我们先把结果导入到一张tmp的表中

select * into tmp from (
select employee as '社員',[星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日]
from (select employee ,weekname,income from week_income) t
pivot
(
sum(income) for weekname in([星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日])
) b
) c select * from tmp

然后,我们将星期一到星期日这几列转换到行上。
2.1 用传统的union all方法。

select 社員 as employee,'星期一' as weekname, 星期一 as income from tmp union all
select 社員 as employee,'星期二' as weekname, 星期二 as income from tmp union all
select 社員 as employee,'星期三' as weekname, 星期三 as income from tmp union all
select 社員 as employee,'星期四' as weekname, 星期四 as income from tmp union all
select 社員 as employee,'星期五' as weekname, 星期五 as income from tmp union all
select 社員 as employee,'星期六' as weekname, 星期六 as income from tmp union all
select 社員 as employee,'星期日' as weekname, 星期日 as income from tmp
order by 社員

2.2 用sqlserver2005以后新增的unpivot方法。

select 社員 as employee, weekname,income
from (select 社員,[星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日] from tmp) a
unpivot
(
income for weekname in ([星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日] )
) b

unpivot是pivot的逆操作,income和weekname都是需要创建的新列,income指代数据的值,weekname指代列名的值。
转换后的结果和我们最初建立的表一模一样
三,动态实现行列旋转
上面的方式,都是代码写了几个固定值旋转,没有实现动态列,扩展性不强。
要实现动态,主要使用拼sql的方式实现,以行转列的传统写法做个例子,其他的可以举一反三。

declare @sql as varchar(4000)
set @sql = 'select employee as ''社員''' select @sql = @sql + ',sum(case weekname when ''' + weekname + ''' then income else 0 end) as ''' + weekname + ''''
from (
select distinct weekname from week_income) a
set @sql =@sql + ' from week_income '
set @sql =@sql + ' group by employee '
print @sql
exec (@sql)

结果也是这样
sql行列旋转的更多相关文章
- SQL 行列倒置
SQL的的行列倒置已经不是新知识了,但在博主的技术咨询期间,仍发现其实有很多人并不了解这块,所以在此专门写一篇博客记录.本文将以Mysql为例,并以数据采集指标信息获取为例子.在下面的例子,你可以在s ...
- SQL行列转换6种方法
在进行报表开发时,很多时候会遇到行列转换操作,很对开发人员针对于SQL级别行列转换操作一直不甚理解,今天正好抽空对其进行了一些简单的总结.这里主要列举3种可以实现SQL行列转换的方法,包括通用SQL解 ...
- SQL行列乾坤大挪移
“生活总是这样,有时候,你需要一个苹果,但别人却给了你一个梨.” 今天dalao邮件里需要添加一张每月累计长长的图,可是,拿到手上的SQL导出数据不符合我最爱的pyecharts的数据输入格式,头大. ...
- 数据透视表sql:用SQL行列转换实现数据透视的一些思考
用SQL行列转换实现数据透视的一些思考 摘要:根据对报表开发过程中碰到的需要用SQL行列转换进行解决的一类查询统计问题的分析,逐步探索求解得到一种较通用的解决思路,并用函数进行实现.该解决思路及函数实 ...
- SQL行列轉換方法(詳細例子)
普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法. 问题:假设有张学生成绩表(tb)如下 ...
- SQL表旋转
在制作报表的时候,有时候会碰到基础资料是依照时间区间去一笔一笔记录的资料,但是使用者在看报表的时候想要将时间区间以横向的方式呈现不是直向的情况出现,又或者基础资料的表数据结构是横向的而使用者在看报表的 ...
- sql行列转换
首先我们建立一张表,名为scoreInfo,各个字段的设计如下图,分别是name,course,score,表示姓名,成绩与分数,如图所示.
- mysql:sql行列转换
今天一个同学遇到一个问题问我了,由于本人平时学习的mysql比较基础,确实没解决,后来google了一下,才知道是sql的一种技法[行列转换],话不多说先上图: 想得到下面的结果: +------+- ...
- SQL行列转换:报表_公司采购表_每个公司各采购了些什么产品
有同学问了个比较典型行列转换的问题,想想,解答如下:数据库有一张表: 是个公司采购表,想转化成如下报表,显示每个公司各采购了些什么产品: 哪些公司采购哪些产品是不确定的,所以报表的列有哪几项是不确定的 ...
随机推荐
- PowerShell添加或修改注册表开机启动项脚本
代码如下: $name = Read-Host "请输入开机启动项的名字(随便起)" $value = Read-Host "请输入开机启动项的值" try{ ...
- [LeetCode_2] Add Two Numbers
LeetCode: 2. Add Two Numbers /** * Definition for singly-linked list. * struct ListNode { * int val; ...
- 【前端】原生event对象和jquery event对象的区别
标准DOM event对象转换成 jQuery event对象 $(event) jQuery event对象转换成 标准DOM event对象 event.originalEvent
- 注释声明:TODO HACK XXX FIXME REVIEW
注释有时候也可以用来给一段代码声明额外的信息.这些声明的格式以单个单词打头并紧跟一个冒号.可以使用的声明如下. TODO: 说明代码还未完成.应当包含下一步要做的事情. HACK: 表明代码实现走了一 ...
- 【前端】CoffeeScript
es6中的双箭头函数可以省略小括号,coffee中不可以 es6: (x) => x * x // 可以 x => x * x // 可以 coffee: (x) => x * x ...
- widgets、dialogs与自动连接(auto-connect)
QMetaObject的自动连接设施(auto-connect facilities)可以自动将槽与信号连接起来,只需要声明和定义一个符合标准命名规则的槽函数 void on_<object n ...
- [OC]宏与const 的使用
Tip: OS日常工作之常用宏定义大全 (摘录文档地址,感觉还不错,例子简单易懂) extern字符串常量,宏定义字符串常量,怎么选? Define与Const专题 extern字符串常量,宏定义字符 ...
- 办公大楼3D指纹门禁系统解决方案
随着人们对工作.生活的自动化水平也提出了越来越高的要求.以大楼安保对出入大楼的外来人员进行登记放行或以铁锁.钥匙和卡为代表的出入管理方式已无法满足需求. 利用科技的手段,实现办公大楼的安全现代化.管理 ...
- 深入理解IOC模式及Unity框架
研究了下,有几篇博客确实已经说得很清楚了 1.IoC模式:http://www.cnblogs.com/qqlin/archive/2012/10/09/2707075.html 这篇博客是通过一个 ...
- 谈谈Memcached与Redis
1. Memcached简介 Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric为首开发的高性能分布式内存缓存服务器.其本质上就是一个 ...