--行列互转
/******************************************************************************************************************************************************
以学生成绩为例子,比较形象易懂

整理人:中国风(Roy)

日期:2008.06.06
******************************************************************************************************************************************************/

--1、行互列
--> --> (Roy)生成測試數據

if not object_id('Class') is null
drop table Class
Go
Create table Class([Student] nvarchar(2),[Course] nvarchar(2),[Score] int)
Insert Class
select N'张三',N'语文',78 union all
select N'张三',N'数学',87 union all
select N'张三',N'英语',82 union all
select N'张三',N'物理',90 union all
select N'李四',N'语文',65 union all
select N'李四',N'数学',77 union all
select N'李四',N'英语',65 union all
select N'李四',N'物理',85
Go
--2000方法:
动态:

declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+' then [Score] else 0 end)'
from Class group by[Course]
exec('select [Student]'+@s+' from Class group by [Student]')

生成静态:

select
[Student],
[数学]=max(case when [Course]='数学' then [Score] else 0 end),
[物理]=max(case when [Course]='物理' then [Score] else 0 end),
[英语]=max(case when [Course]='英语' then [Score] else 0 end),
[语文]=max(case when [Course]='语文' then [Score] else 0 end)
from
Class
group by [Student]

GO
动态:

declare @s nvarchar(4000)
Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course]
exec('select * from Class pivot (max([Score]) for [Course] in('+@s+'))b')

生成静态:
select *
from
Class
pivot
(max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b

生成格式:
/*
Student 数学 物理 英语 语文
------- ----------- ----------- ----------- -----------
李四 77 85 65 65
张三 87 90 82 78

(2 行受影响)
*/

------------------------------------------------------------------------------------------
go
--加上总成绩(学科平均分)

--2000方法:
动态:

declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+' then [Score] else 0 end)'
from Class group by[Course]
exec('select [Student]'+@s+',[总成绩]=sum([Score]) from Class group by [Student]')--加多一列(学科平均分用avg([Score]))

生成动态:

select
[Student],
[数学]=max(case when [Course]='数学' then [Score] else 0 end),
[物理]=max(case when [Course]='物理' then [Score] else 0 end),
[英语]=max(case when [Course]='英语' then [Score] else 0 end),
[语文]=max(case when [Course]='语文' then [Score] else 0 end),
[总成绩]=sum([Score]) --加多一列(学科平均分用avg([Score]))
from
Class
group by [Student]

go

--2005方法:

动态:

declare @s nvarchar(4000)
Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course] --isnull(@s+',','') 去掉字符串@s中第一个逗号
exec('select [Student],'+@s+',[总成绩] from (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a
pivot (max([Score]) for [Course] in('+@s+'))b ')

生成静态:

select
[Student],[数学],[物理],[英语],[语文],[总成绩]
from
(select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a --平均分时用avg([Score])
pivot
(max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b

生成格式:

/*
Student 数学 物理 英语 语文 总成绩
------- ----------- ----------- ----------- ----------- -----------
李四 77 85 65 65 292
张三 87 90 82 78 337

(2 行受影响)
*/

go

--2、列转行
--> --> (Roy)生成測試數據

if not object_id('Class') is null
drop table Class
Go
Create table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语文] int)
Insert Class
select N'李四',77,85,65,65 union all
select N'张三',87,90,82,78
Go

--2000:

动态:

declare @s nvarchar(4000)
select @s=isnull(@s+' union all ','')+'select [Student],[Course]='+quotename(Name,'''')--isnull(@s+' union all ','') 去掉字符串@s中第一个union all
+',[Score]='+quotename(Name)+' from Class'
from syscolumns where ID=object_id('Class') and Name not in('Student')--排除不转换的列
order by Colid
exec('select * from ('+@s+')t order by [Student],[Course]')--增加一个排序

生成静态:
select *
from (select [Student],[Course]='数学',[Score]=[数学] from Class union all
select [Student],[Course]='物理',[Score]=[物理] from Class union all
select [Student],[Course]='英语',[Score]=[英语] from Class union all
select [Student],[Course]='语文',[Score]=[语文] from Class)t
order by [Student],[Course]

go
--2005:

动态:

declare @s nvarchar(4000)
select @s=isnull(@s+',','')+quotename(Name)
from syscolumns where ID=object_id('Class') and Name not in('Student')
order by Colid
exec('select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in('+@s+'))b')

go
select
Student,[Course],[Score]
from
Class
unpivot
([Score] for [Course] in([数学],[物理],[英语],[语文]))b

生成格式:
/*
Student Course Score
------- ------- -----------
李四 数学 77
李四 物理 85
李四 英语 65
李四 语文 65
张三 数学 87
张三 物理 90
张三 英语 82
张三 语文 78

(8 行受影响)
*/

===========================(例二)===================================

--行转列问题 
--建立測試環境 
Create Table TEST 
(DATES Varchar(6), 
EMPNO Varchar(5), 
STYPE Varchar(1), 
AMOUNT Int) 
--插入數據 
Insert TEST Select '200605', '02436', 'A', 5 
Union All Select '200605', '02436', 'B', 3 
Union All Select '200605', '02436', 'C', 3 
Union All Select '200605', '02436', 'D', 2 
Union All Select '200605', '02436', 'E', 9 
Union All Select '200605', '02436', 'F', 7 
Union All Select '200605', '02436', 'G', 6 
Union All Select '200605', '02438', 'A', 7 
Union All Select '200605', '02438', 'B', 8 
Union All Select '200605', '02438', 'C', 0 
Union All Select '200605', '02438', 'D', 3 
Union All Select '200605', '02438', 'E', 4 
Union All Select '200605', '02438', 'F', 5 
Union All Select '200605', '02438', 'G', 1 
GO 
--測試 
--如果STYPE固定,可以這麼寫 
Select 
DATES, 
EMPNO, 
SUM(Case STYPE When 'A' Then AMOUNT Else 0 End) As A, 
SUM(Case STYPE When 'B' Then AMOUNT Else 0 End) As B, 
SUM(Case STYPE When 'C' Then AMOUNT Else 0 End) As C, 
SUM(Case STYPE When 'D' Then AMOUNT Else 0 End) As D, 
SUM(Case STYPE When 'E' Then AMOUNT Else 0 End) As E, 
SUM(Case STYPE When 'F' Then AMOUNT Else 0 End) As F, 
SUM(Case STYPE When 'G' Then AMOUNT Else 0 End) As G 
From TEST 
Group By DATES,EMPNO 
Order By DATES,EMPNO 
--如果STYPE不固定,用動態語句 
Declare @S Varchar(1000) 
Set @S='' 
Select @S=@S+',SUM(Case STYPE When '''+STYPE+''' Then AMOUNT Else 0 End) As '+STYPE From (Select Distinct STYPE From TEST) A Order By STYPE 
Set @S='Select DATES,EMPNO'+@S+' From TEST Group By DATES,EMPNO Order By DATES,EMPNO' 
EXEC(@S) 
GO 
--如果被转置的是数字类型的话,应用下列语句 
DECLARE @S VARCHAR(1000) 
SET @S='SELECT DATES,EMPNO ' 
SELECT @S=@S+',['+STYPE+']=SUM(CASE WHEN STYPE='''+STYPE+''' THEN AMOUNT ELSE 0 END)' 
FROM (Select Distinct STYPE From TEST) A Order By STYPE 
SET @S=@S+' FROM TEST GROUP BY DATES,EMPNO' 
EXEC(@S)

如果是列转行的话直接Union All就可以了 
例如 : 
city style color 46 48 50 52 
长沙 S6MF01002 152 1 2 2 1 
长沙 S6MF01002 201 1 2 2 1 
上面到下面的样子 
city style color size qty 
长沙 S6MF01002 152 46 1 
长沙 S6MF01002 152 48 2 
长沙 S6MF01002 152 50 2 
长沙 S6MF01002 152 52 1 
长沙 S6MF01002 201 46 1 
长沙 S6MF01002 201 48 2 
长沙 S6MF01002 201 50 2 
长沙 S6MF01002 201 52 1 
Select City,Style,Color,[46] From Test 
Union all 
Select City,Style,Color,[48] From Test 
Union all 
Select City,Style,Color,[50] From Test 
Union all 
Select City,Style,Color,[52] From Test 
就可以了

===========================(例三)===============================

CREATE TABLE tb (GroupName VARCHAR(64),Price decimal(10,2))
INSERT INTO tb
SELECT 'VIP客户',1011.00
UNION ALL
SELECT'白金卡会员',225.00
UNION ALL
SELECT'白金卡会员1',225.00
UNION ALL
SELECT'白金卡会员2',225.00
UNION ALL
SELECT'白金卡会员3',225.00
UNION ALL
SELECT'白金卡会员4',225.00
UNION ALL
SELECT'白金卡会员4',225.00

--DROP TABLE tb
declare @s nvarchar(max)
set @s=''
Select @s=@s+','+quotename(GroupName)+'=max(case when [GroupName]='+quotename(GroupName,'''')+' then [price] else 0 end)'
from tb group by GroupName
SELECT @s=SUBSTRING(@s,2,LEN(@s))

EXEC ('select '+@s+' from tb ')

/*
VIP客户 白金卡会员 白金卡会员1 白金卡会员2 白金卡会员3 白金卡会员4
--------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
1011.00 225.00 225.00 225.00 225.00 225.00

(1 行受影响)

*/

mssql 数据库表行转列,列转行 比较经典的更多相关文章

  1. Akka(41): Http:DBTable-rows streaming - 数据库表行交换

    在前面一篇讨论里我们介绍了通过http进行文件的交换.因为文件内容是以一堆bytes来表示的,而http消息的数据部分也是byte类型的,所以我们可以直接用Source[ByteString,_]来读 ...

  2. Atitit.mssql 数据库表记录数and 表体积大小统计

    Atitit.mssql 数据库表记录数and 表体积大小统计 1. EXEC   sp_MSforeachtable   "EXECUTE   sp_spaceused   '?'&quo ...

  3. mysql数据库表修改某一列的类型

    下面列出:1.增加一个字段alter table user add COLUMN new1 VARCHAR(20) DEFAULT NULL; //增加一个字段,默认为空alter table use ...

  4. MSSQL数据库表加锁

    所指定的表级锁定提示有如下几种: 1. HOLDLOCK: 在该表上保持共享锁,直到整个事务结束,而不是在语句执行完立即释放所添加的锁. 2. NOLOCK:不添加共享锁和排它锁,当这个选项生效后,可 ...

  5. 使用SqlDependency监听MSSQL数据库表变化通知

    SqlDependency提供了这样一种机制,当被监测的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让系统自动更新数据(或缓存)的目的. ...

  6. 创建动态MSSQL数据库表的方法

    代码如下: ImportsSystem.Data ImportsSystem.Data.SqlClient PublicClassForm1 InheritsSystem.windows.Forms. ...

  7. MSSQL数据库表结构无法更改

    工具->Designers-> 组织保存要求重新创建表的更改 -> 把这个钩去掉就可以了    

  8. EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的

    我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...

  9. 在oracle数据库表中没有添加rowid字段为什么会出现?

    rowid 是 oracle 数据库表中的伪列, rowid 首先是一种数据类型,它唯一标识一条记录物理位置, 基于64位编码的18个字符显示.因为 rowid 是伪列, 所以并未真的存储在表中,但可 ...

随机推荐

  1. P2084 进制转换

    原题链接 https://www.luogu.org/problemnew/show/P2084 这个题的思路就是先将输入的数字存到字符数组里,然后求出这一串数字中的非0元素的个数total,并记录最 ...

  2. Min_25 筛小结

    Min_25 筛这个东西,完全理解花了我很长的时间,所以写点东西来记录一些自己的理解. 它能做什么 对于某个数论函数 \(f\),如果满足以下几个条件,那么它就可以用 Min_25 筛来快速求出这个函 ...

  3. Codeforces 700 C. Break Up(Tarjan求桥)

    题意 给你一个有 \(n\) 个点, \(m\) 条边的无向图,每条有边权 \(w_i\) ,现在要选择至多两条边断开,使得 \(S, T\) 不连通,并且使得边权和尽量小. \(n \le 1000 ...

  4. [luogu2051][bzoj1801][AHOI2009]chess中国象棋【动态规划】

    题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...

  5. 临时处理小记:把Numpy的narray二进制文件转换成json文件

    临时处理一个Numpy的二进制文件,分析知道里面是dict类型,简单小记一下,如果Numpy和Python基础不熟悉可以看我之前写的文章 In [1]: %%time import numpy as ...

  6. Ubuntu18.04 下的Gif录制工具

    正文: 开源地址:https://github.com/phw/peek Linux包相关的知识如果不知道可以看以前讲的:https://www.cnblogs.com/dunitian/p/9095 ...

  7. javascript正则表达式---正向预查

    什么是正向预查?这里有腾讯招聘的一个例子: 如何给一串数字用千分制表示?比如9999999999变成9,999,999,999.这样一个问题你会怎么答呢?博主js正则学的不咋样,然后用操作字符串的办法 ...

  8. A1017. Queueing at Bank

    Suppose a bank has K windows open for service. There is a yellow line in front of the windows which ...

  9. java的抽象方法

    抽象类所起的功能就像定义模板的功能,子类必须继承抽象类,因此不能用final修饰 http://blog.csdn.net/wei_zhi/article/details/52736350 抽象类的函 ...

  10. C# 实现身份验证之WebApi篇

    今天再来总结关于如何实现WebApi的身份验证,以完成该系列所有文章,WebApi常见的实现方式有:FORM身份验证.集成WINDOWS验证.Basic基础认证.Digest摘要认证  第一种:FOR ...