当前位置:首页 » 编程语言 » sql行列动态转换
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

sql行列动态转换

发布时间: 2023-08-10 02:17:22

sql行列转换(sql行列转换最简单的方法)

很遗憾贺陆行列之间不是那么随便说转换就转换的

行描述的是一个对象列只是对象的一个属性禅悔顷

java里说的是

万物皆对象

只要是对象就可以吧特征抽象成一个类

这就对应于数据库的表

肤浅的说

表就相当于一个类

比如人这一类有手属性,脚属性,头属性....就不多列举了

他们构成了一个人(人类表的一行)而N多拥有相同特征的人就组成了人类(人类这个表)

楼主你现在要做的事情无异于要把人给肢解要把每一个人的手或脚或其他单一部件代替某一个人的全部部件(当做属性)

说简单一点就是楼主你要的效果就是让人类表的美一个人都不同而且不同的方式还很奇怪一个前敏人只有手一个又只有脚一直有只有头.....最后整的相同特征全无

这完全不符合归为一类化为一个表的初衷嘛

不说能不能化行为列

就算可以换行成列那又有什么意思呢?

完全没有意义嘛

而且在实际开发中也不会有化行成列的需求

② SQL行转列应用的动态实现方式

SQL行转列的需求,在项目中还是经常可见的,尤其报表类的应用,更是非常广泛!上期我们讲了SQL行转列的静态实现方式,本期搞一下行转列的动态实现方案,解决方案并不唯一,这里采用存储过程的实现方式!

接下来我们详细讲解下SQL动态行转列的实现步骤:

这里还是老套路,IT编程人入门的经典学生选课表系列,学生表、课程表、成绩表!就拿这套耳熟能详的表结构进行讲解!

插入模拟的数据,用于动态行转案例的使用!

这一步相对还是比较重要,毕竟我们要在一个静态的行转列基础之上,构建动态的行转列应用,课程数据会有动态变化,学生也会选择新开的课程,这样静态模式势必不会有效,但参照静态模板,去开发动态的模式,则更加有参照性!

通过测试,数据效果没有问题,正是我们期待的样子!

动态行转列无疑需要使用SQL编程的技术,动态的递归课程名称,这样才可以一劳永逸的解决问题!

先编写动态的SQL脚本

测试结果与静态SQL完全一致,看来问题已经解决,接下来就是优化的问题了!

将上述的动态脚本封装成存储过程,第一可以尽量地提升查询效率,第二方便代码段的调用!

封装完存储过程,我们再执行一下,看看结果!果然没有任何问题,与预期完全一致!

这时候我们更改一下数据,课程表中新增物理、化学两门课程,诺克萨斯之手分别选择了两门课程,盖伦仅仅选择了化学,武器大师逃学,俩门课都没有选择。

数据改变之后,我们继续测试一下,再次执行我们编写好的存储过程,结果非常完美,随着数据的变化,查询的结果集也是对应的变化,非常NICE,大功告成了!

连续俩篇的文章更新,SQL行转列在项目中的应用都已经涵盖了。即将步入年底了,肯定有很多小伙伴被客户、领导追着搞各种报表,希望对小伙伴们有些许的帮助。#学编程# #互联网# #IT#

③ sql 如何动态多行转多列

使用存储过程。
方法如下:
1、先查询出表里面的列名称
2、行列转换

举例
1、查询student字段名
SELECT
a.colorder as _colOrder, --字段序号
a.name as _colName --字段名
FROM syscolumns a left join systypes b
on a.xtype=b.xusertype
inner join sysobjects d
on a.id=d.id and d.xtype='U' and d.name<> 'dtproperties'
left join syscomments e
on a.cdefault=e.id
left join sys.extended_properties g
on a.id=g.major_id AND a.colid = g.minor_id
where d.name='student' --所要查询的表
order by a.id,a.colorder

2、行列转换
SELECT
MAX (CASE WHEN SetupID = 1 THEN SetupName ELSE NULL END ) AS [1],
MAX (CASE WHEN SetupID = 2 THEN SetupName ELSE NULL END ) AS [2],
MAX (CASE WHEN SetupID = 3 THEN SetupName ELSE NULL END ) AS [3],
MAX (CASE WHEN SetupID = 4 THEN SetupName ELSE NULL END ) AS [4]
......
FROM table

④ sql动态多行转列,PIVOT怎么能转两列

楼上那个用过sqlserver吗?

PIVOT是支持的!!!!!

不过看你的语法,肯定报错。PIVOT最好基于SELECT * 并且先把全部需求的字段转换未列:

select * from

(select CONVERT(varchar(100),年月)+'受理' 栏位,sum(受理数量) 数量 from

表a

GROUP BY 年月

UNION ALL

select CONVERT(varchar(100),年月)+'办结'栏位,sum(办结数量) 数量 from

表a

GROUP BY 年月)v

PIVOT ( MAX(v.数量) FOR v.栏位 IN ( [2019-01受理],

[2019-02受理],

[2019-03受理],

[2019-04受理],

[2019-01办结],

[2019-02办结],

[2019-03办结],

[2019-04办结] )) 网络知道回答用

⑤ sql 2000 结合两张表“动态”实现 行转列

第一步,sql拼接:

select'sum(casewhenarea='''||area||'''then1else0end)'asrows
fromtable

然后取得上面结果的记录集,组合拼接 进行第二步,示例如下:

selectbDate,sum(casewhenarea='保养一区'then1else0end)as保养一区,
sum(casewhenarea='保养二区'then1else0end)as保养二区,
sum(casewhenarea='保养三区'then1else0end)as保养三区,
sum(casewhenarea='保养四区'then1else0end)as保养四区,
sum(casewhenarea='保养五区'then1else0end)as保养五区

fromtable
groupbybDate

⑥ SQL 行列转换

行列转换等经典SQL语句

1.--行列转换

原表: 姓名 科目 成绩
张三 语文 80
张三 数学 90
张三 物理 85
李四 语文 85
李四 物理 82
李四 英语 90
李四 政治 70
王五 英语 90

转换后的表: 姓名 数学 物理 英语 语文 政治
李四 0 82 90 85 70
王五 0 0 90 0 0
张三 90 85 0 80 0

实例:
create table cj --创建表cj
(
ID Int IDENTITY (1,1) not null, --创建列ID,并且每次新增一条记录就会加1
Name Varchar(50),
Subject Varchar(50),
Result Int,
primary key (ID) --定义ID为表cj的主键
);
--Truncate table cj
--Select * from cj
Insert into cj
Select '张三','语文',80 union all
Select '张三','数学',90 union all
Select '张三','物理',85 union all
Select '李四','语文',85 union all
Select '李四','物理',82 union all
Select '李四','英语',90 union all
Select '李四','政治',70 union all
Select '王五','英语',90
--行列转换
Declare @sql varchar(8000)
Set @sql = 'Select Name as 姓名'
Select @sql = @sql + ',sum(case Subject when '''+Subject+''' then Result else 0 end) ['+Subject+']'
from (select distinct Subject from cj) as cj --把所有唯一的科目的名称都列举出来
Select @sql = @sql+' from cj group by name'
Exec (@sql)

2. 行列转换--合并
原表: 班级 学号
1 1
1 2
1 3
2 1
2 2
3 1
转换后的表: 班级 学号
1 1,2,3
2 1,2
3 1

实例:
Create table ClassNo --创建表ClassNo
(
ID Int IDENTITY(1,1) not null, --创建列ID,并且每次新增一条记录就会加1
Class Varchar(50), --班级列
Number Varchar(50), --学号列
Primary Key(ID) --定义ID为表ClassNo的主键
);
--Truncate Table ClassNo
--Select * from ClassNo
Insert Into ClassNo
Select 1,1 Union all
Select 1,2 Union all
Select 1,3 Union all
Select 2,1 Union all
Select 2,2 Union all
Select 3,1

创建一个合并的函数
--Drop Function KFReturn
Create Function KFReturn(@Class Varchar(50))
Returns Varchar(8000)
as
Begin
Declare @str Varchar(8000)
Set @str = ''
Select @str = @str + cast(Number as Varchar(50)) + ',' from ClassNo Where Class = @Class
Set @str = SubString(@str,1,len(@str)-1)
Return(@str)
End

--调用自定义函数得到结果
Select Distinct Class,dbo.KFReturn(Class) From ClassNo

3:列转行
--Drop Table ColumnToRow
Create table ColumnToRow
(
ID Int IDENTITY(1,1) not null, --创建列ID,并且每次新增一条记录就会加1
a int,
b int,
c int,
d int,
e int,
f int,
g int,
h int,
Primary Key(ID) --定义ID为表ColumnToRow的主键
);
--Truncate Table ColumnToRow
--Select * from ColumnToRow
Insert Into ColumnToRow
Select 15,9,1,0,1,2,4,2 Union all
Select 22,34,44,5,6,7,8,7 Union all
Select 33,44,55,66,77,88,99,12

Declare @sql Varchar(8000)
Set @sql = ''
Select @sql = @sql + rtrim(name) + ' from ColumnToRow union all Select ' from SysColumns Where id = object_id('ColumnToRow')
Set @sql = SubString(@sql,1,len(@sql)-70)
--70的长度就是这个字符串'from ColumnToRow union all Select ID from ColumnToRow union all Select ',因为它会把ID这一列的值也算进去,所以要把它截掉
Exec ('Select ' + @sql + ' from ColumnToRow')

⑦ sql行列转换

--测试环境MSSQL2008
--先创建一个表值函数,负责字符串拆分
CreateFunction[dbo].[f_split1](@SourceSqlVarchar(8000),@StrSeprateVarchar(2))
Returns@tempTable(idIntIdentity(1,1),colVarchar(100))
As
begin
Declare@chasVarchar(100)
Set@SourceSql=@SourceSql+@StrSeprate
While(@SourceSql<>'')
Begin
Set@ch=left(@SourceSql,Charindex(@StrSeprate,@SourceSql,1)-1)
Insert@temp(col)Values(@ch)
Set@SourceSql=Stuff(@SourceSql,1,Charindex(@StrSeprate,@SourceSql,1),'')
End
Return
End
go

--建表
createtable#table(namenvarchar(500),valuenvarchar(max))

--插入数据
insertinto#tablevalues('aaa','45,44,44,44,43,43,43,43,43,43')
insertinto#tablevalues('bbb','45,44,44,44,44,44,44,44,44,43')
insertinto#tablevalues('ccc','13,12,12,12,4')

--由于N不固定,下面就动态生成SQL
Declare@Iint
Declare@WVarchar(1000)=''
Declare@SVarchar(4000)=''
Declare@SqlVarchar(8000)=''
select@I=max(len(value)-len(replace(value,',','')))from#table
While@I>0
Begin
Set@W=',['+Convert(Varchar(10),@I)+']'+@W
Set@S=',['+Convert(Varchar(10),@I)+']AsTop'+Convert(Varchar(10),@I)+@S
Set@I=@I-1
End
Set@Sql='
selectname'+@S+'from#table
outerapplydbo.f_split1(value,'','')
pivot
(
max(col)
For
idin('+stuff(@W,1,1,'')+')
)p
orderbyname'

--执行
Exec(@sql)


⑧ SQL 行列转换

前段时间有人问了一个问题,就是SQL的行列转换,当时有点懵没答上来,后来细细想一想,其实最近的一个项目就已经用到了。
基础数据如下:

要求根据当年的月份去统计出每一个ID的汇总金额。就是把行中的月切换到列中。
最后效果如下:

参考资料: https://technet.microsoft.com/zh-cn/library/ms177410(v=sql.105).aspx#%E5%A4%8D%E6%9D%82%20PIVOT%20%E7%A4%BA%E4%BE%8B

带批注的 PIVOT 语法。

如果聚合函数与 PIVOT 一起使用,则计算聚合时将不考虑出现在值列中的任何空值。

新建两张表

查询结果

--UNPIVOT 函数

--单纯用SQL 处理 ,原理很简单,就是对每个需要置换的列单独处理出来

最终效果:

--用上面的结果新建表

--PIVOT

-- SQL直接处理,先用CASE 语句将每行处理出来,然后在用聚合去处理合并相同ID的行。

⑨ sql动态实现行列转换

题:假设有张学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
想变成(得到如下结果):
姓名 语文 数学 物理
---- ---- ---- ----
李四 74 84 94
张三 74 83 93
-------------------
*/

create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
insert into tb values('张三' , '语文' , 74)
insert into tb values('张三' , '数学' , 83)
insert into tb values('张三' , '物理' , 93)
insert into tb values('李四' , '语文' , 74)
insert into tb values('李四' , '数学' , 84)
insert into tb values('李四' , '物理' , 94)
go

--SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)
select 姓名 as 姓名 ,
max(case 课程 when '语文' then 分数 else 0 end) 语文,
max(case 课程 when '数学' then 分数 else 0 end) 数学,
max(case 课程 when '物理' then 分数 else 0 end) 物理
from tb
group by 姓名

--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
declare @sql varchar(8000)
set @sql = 'select 姓名 '
select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
from (select distinct 课程 from tb) as a
set @sql = @sql + ' from tb group by 姓名'
exec(@sql)