MSSQL纵列转横列
在工作中我们一般会遇到将纵列转横列的需求,具体代码:
1.建表
CREATE TABLE [dbo].[AcrossChangeEndLong](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Subject] [nvarchar](50) NOT NULL,
[Score] [int] NOT NULL,
CONSTRAINT [PK_AcrossChangeEndLong] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO
SET IDENTITY_INSERT [dbo].[AcrossChangeEndLong] ON GO
INSERT [dbo].[AcrossChangeEndLong] ([Id], [Name], [Subject], [Score]) VALUES (1, N'张三', N'语文', 100)
GO
INSERT [dbo].[AcrossChangeEndLong] ([Id], [Name], [Subject], [Score]) VALUES (3, N'李四', N'语文', 80)
GO
INSERT [dbo].[AcrossChangeEndLong] ([Id], [Name], [Subject], [Score]) VALUES (4, N'张三', N'英语', 80)
GO
INSERT [dbo].[AcrossChangeEndLong] ([Id], [Name], [Subject], [Score]) VALUES (5, N'李四', N'英语', 50)
GO
INSERT [dbo].[AcrossChangeEndLong] ([Id], [Name], [Subject], [Score]) VALUES (6, N'张三', N'数学', 55)
GO
INSERT [dbo].[AcrossChangeEndLong] ([Id], [Name], [Subject], [Score]) VALUES (7, N'李四', N'数学', 34)
GO
SET IDENTITY_INSERT [dbo].[AcrossChangeEndLong] OFF
GO
ALTER TABLE [dbo].[AcrossChangeEndLong] ADD CONSTRAINT [DF_AcrossChangeEndLong_Score] DEFAULT ((0)) FOR [Score]
GO
2.具体SQL
SELECT Name AS '姓名',
MAX(CASE [Subject]
WHEN '语文' THEN Score
ELSE 0
END) AS '语文' ,
MAX(CASE [Subject]
WHEN '英语' THEN Score
ELSE 0
END) AS '英语' ,
MAX(CASE [Subject]
WHEN '数学' THEN Score
ELSE 0
END) AS '数学'
FROM dbo.AcrossChangeEndLong
GROUP BY Name ORDER BY Name
如果到时候增加了科目,比如增加了化学,这时候为了再次修改,我们可以弄成动态的(根据列自动增加),这里使用的是动态拼接SQL,会根据科目的增加而增加列,具体SQL如下
DECLARE @sql VARCHAR(8000)
SET @sql = 'SELECT [Name],'
SELECT @sql = @sql + 'SUM(CASE [Subject] WHEN ''' + [Subject]
+ ''' THEN [Score] ELSE 0 END) AS ''' + [Subject] + ''','
FROM ( SELECT DISTINCT
[Subject]
FROM dbo.AcrossChangeEndLong
) AS a
SELECT @sql = LEFT(@sql, LEN(@sql) - 1)
+ ' FROM [AcrossChangeEndLong] GROUP BY [Name]'
PRINT ( @sql )
EXEC(@sql)
另外在SQL Server 2005之后有了一个专门的PIVOT 和 UNPIVOT 关系运算符做行列之间的转换
注意:这种不能用于 eg: CASE [Subject] WHEN '数学' THEN Score ELSE 0 END 如果Then 后面是1(统计的时候会用到)而不是具体字段的时候,使用会报错,具体SQL如下
SELECT *
FROM ( SELECT Name AS '姓名',
Subject ,
Score
FROM dbo.AcrossChangeEndLong
) p PIVOT ( MAX(Score) FOR Subject IN ( [数学], [英语], [语文] ) ) AS pvt
ORDER BY pvt.姓名
使用Pivot动态拼接SQL:
DECLARE @sql_str VARCHAR(MAX)
DECLARE @sql_col VARCHAR(MAX)
SELECT @sql_col = ISNULL(@sql_col + ',', '') + QUOTENAME([Subject])
FROM dbo.AcrossChangeEndLong
GROUP BY [Subject]
SET @sql_str = '
SELECT * FROM (
SELECT [Name],[Subject],[Score] FROM [AcrossChangeEndLong]) p PIVOT
(SUM([Score]) FOR [Subject] IN ( ' + @sql_col + ') ) AS pvt
ORDER BY pvt.[Name]'
PRINT ( @sql_str )
EXEC (@sql_str)
具体效果:

扩展:可能我们需要加一个统计行,可以用UNION ALL连接 上一个表的结果【可以将结果插入临时表】,再用函数SUM求和各个列
MSSQL纵列转横列的更多相关文章
- (转载)SQL语句,纵列转横列
SQL语句,纵列转横列 Feed: 大富翁笔记 Title: SQL语句,纵列转横列 Author: wzmbox Comments sTable.db库位 货物编号 库存数1 0101 501 01 ...
- MSSQL横列转纵列
上篇我们说到了纵列转横列,这篇讲下横列转纵列,具体代码: 1.建表 CREATE TABLE [dbo].[EndLongChangeAcross]( ,) NOT NULL, ) NOT NULL, ...
- CSS实现横列布局的方法总结
一.使用float实现横列布局的方法 如下面所示:DIV1和DIV2都可以选择向左或者向右浮动50%来实现展示在同一行 div1 div2 实现下面图片中布局的css样式如下: 分析: 1.第一行第一 ...
- mssql Sqlver 修改标识列方法
摘自: http://www.cnblogs.com/badboy2008/articles/1145465.html MSSQL Server修改标识列方法 ----允许对系统表进行更新exec ...
- 一、CSS实现横列布局的方法总结
一.使用float实现横列布局的方法 如下面所示:DIV1和DIV2都可以选择向左或者向右浮动50%来实现展示在同一行 div1 div2 实现下面图片中布局的css样式如下: 分析: 1.第一行第一 ...
- mssql 获取自增列起始及增量
--首先创建一个表 CREATE TABLE [dbo].[abcd]( ,) NOT NULL, ) NULL, ) NULL ) ON [PRIMARY] --获取起始值 SELECT IDENT ...
- MSSQL—按照某一列分组后取前N条记录
以前在开发的时候遇到过一个需求,就是要按照某一列进行分组后取前几条数据,今天又有同事碰到了,帮解决了之后顺便写一篇博客记录一下. 首先先建一个基础数据表,代码如下: IF OBJECT_ID(N'Te ...
- mssql 动态行转列。
)) ,'张三' ,'李四' ,'王五' select * from #a a b ----------- ---- 张三 李四 王五 ( 行受影响) --行转列,步骤:''+张三+],[+王五+], ...
- mssql sqlserver 表增加列后,视图不会自动更新相关列的两种解决方法分享
摘要: 今天对物理数据表,进行增加列操作后,程序一直显示无法找到相应列,通过仔细比对发现,视图中无相应列更新,下文将具体的解决方法分享如下: 例: create view vw_test as sel ...
随机推荐
- 《Cracking the Coding Interview》——第5章:位操作——题目3
2014-03-19 05:57 题目:给定一个整数N,求出比N大,而且二进制表示中和N有相同个数的‘1’的最小的数,比如3是‘11’,接下来的5是‘101’,再接下来的6是‘110’. 解法:从低位 ...
- 《数据结构》C++代码 堆(优先队列)
堆,是优先队列最常用的一种实现方式.在优先队列中,每个元素都被赋予了一个优先级,而每次出队时都让优先级最高的元素出队.堆,则是一种存储优先队列的方法,特指以一棵树形式存储的优先队列.最常用的是二叉堆, ...
- phpStorm9.0 +xampp+chrome php调试环境配置!
不多说,直接上step by step: 1.xampp配置 看看我的XAMPP版本: 修改配置文件,该打开打开,该加上加上,结果如下(当前需要重新启动apache,配置才会生效): [XDebug] ...
- Linux之Permission denied没有权限
在Linux上启动solr时,出现-bash: ./solr: Permission denied的问题. 最简单的解决方式: chmod 777 solr 傻瓜式直接赋予权限
- 解决Navicat for MySQL 连接 Mysql 8.0.11 出现1251- Client does not support authentication protocol 错误
安装MySQL8.0之后,使用Navicat连接数据库,报1251错误. 上网搜索解决方案,网上说出现这种情况的原因是:mysql8 之前的版本中加密规则是mysql_native_password, ...
- python 学习分享-socketserver
SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端.即:每个客户端请求连接到服务器时,Socket服务端都会在服务器 ...
- winform对图片进行灰度处理
//图片进行灰度处理 //originalImage为原图像 返回灰度图像 private Bitmap GrayImage(Bitmap originalImage) { ImageAttribut ...
- Action参数和View、Json、重定向
一.Action 1.Action参数: 普通参数.Model类.FormCollection (1).普通参数 Index(string name,int age) 框架会自动把用户请求的Que ...
- IPMITool driver
官网链接: https://docs.openstack.org/ironic/latest/admin/drivers/ipmitool.html IPMITool driver 概述IPMI(In ...
- 【志银】#define lowbit(x) ((x)&(-x))原理详解
分析下列语句 #define lowbit(x) ((x)&(-x)) 可写成下列形式: int Lowbit(x) { return x&(-x); } 例1:x = 1 十进制转二 ...