Ⅰ sql 将横向数据转为纵向记录
使用union连接SQL语句,可以实现常见的SQL行转列运用。
以图中表格为例:
需要注意,如果有需要显示重复记录,把union 改成 union all
Ⅱ SQL数据横列变竖列
以下方法适用于任意多的科目:
--先建立函数,功能是根据给出的姓名,到表中去查找所选科目及成绩并横向列示出来.
CREATE FUNCTION getcoldata
(@XM VARCHAR(18))
RETURNS varchar(1000)
AS
BEGIN
DECLARE @deli VARCHAR(2)
set @deli=' '
declare @f1 varchar(100),@F2 DECIMAL(12,1),@result varchar(1000),@sn0 int
set @result=''
declare ddcursor cursor for select 选修科目,成绩 from 表名 where 姓名=@XM order by 选修科目
open ddcursor
fetch next from ddcursor into @f1,@F2
while @@fetch_status!=-1
begin
set @result=@result+@deli+isnull(@f1,'')+':'+ISNULL(CONVERT(VARCHAR,@F2),'')
fetch next from ddcursor into @f1,@F2
end
close ddcursor
deallocate ddcursor
return (@result)
end
GO
--使用方法:
select 姓名,科目及成绩=dbo.getcoldata(姓名) from (SELECT DISTINCT 姓名 from 表名) a
结果是这样的
姓名 科目与成绩
张三 计算机:75 高等数学:80 物理:77
李四 高等数学:55 微积分:87
王五 语文:78
=============
我这么看您的问题:
1.查询是用来输出的,不是用来统计的:您的这种结果即使用分开字段也是很不容易统计的,要想统计还是原表比较方便.
就是说:这种查询结果更方便输出\查看,原表更方便于作统计.
所以,我劝您,比较科学的作法是保留原表,可以方便的作出包括本查询在内的各种查询.而您如果只保留查询后的表,即使用字段是分开的,那么将很难再作其它统计和查询.因为数据太不规范.
2.可以输出各门分开的EXCEL表:如果您想输出到EXCEL表,您要以把函数中的分隔符改成逗点或制表符(CHAR(9)),直接存成CSV或XLS文档就成了.
3.完全按照您的结果也能输出.但今天我没空了,给你个提示:
先看看我以前的回答中,有一些是关于加序号的,加上序号后就好说了.
===========
加到200分,我就开始为您作分开字段的查询.(办法我知道,但是很麻烦啊)
===============================================
与您的要求完全相同的查询:
为了清楚,先建立一个查询,给每人的科目加序号,如果不理解,执行一下SELECT * FROM MYVIEWNAME就知道了:
=====================
视图改一下:
create view myviewname
as
select 姓名,科目,成绩,序号=(select count(1) from tablename a where a.姓名=b.姓名 and a.科目>=b.科目) from
(select * from tablename where 状态='有效') --以子查询替换了TABLENAME,够直观吧?
b --视图加上了序号字段
go
然后,这就是您要的查询,根据每人所选科目的最大数,可以无限向后延伸,加入科目6,科目7等:
select a.姓名,
科目1=isnull(t1.科目,''),
成绩1=isnull(t1.成绩,''),
科目2=isnull(t2.科目,''),
成绩2=isnull(t2.成绩,''),
科目3=isnull(t3.科目,''),
成绩3=isnull(t3.成绩,''),
科目4=isnull(t4.科目,''),
成绩4=isnull(t4.成绩,''),
科目5=isnull(t5.科目,''),
成绩5=isnull(t5.成绩,'')
from (SELECT DISTINCT 姓名 from tablename) a
left join myviewname t1 on t1.姓名=a.姓名 and t1.序号=1
left join myviewname t2 on t2.姓名=a.姓名 and t2.序号=2
left join myviewname t3 on t3.姓名=a.姓名 and t3.序号=3
left join myviewname t4 on t4.姓名=a.姓名 and t4.序号=4
left join myviewname t5 on t5.姓名=a.姓名 and t5.序号=5
好了,加到200分再选择正确答案!
Ⅲ SQL 横排变竖排的问题
给例子远比你贴代码快,
SELECT name,
SUM(CASE subject WHEN '语文' THEN Result ELSE 0 END),
SUM(CASE subject WHEN '数学' THEN Result ELSE 0 END),
SUM(CASE subject WHEN '物理' THEN Result ELSE 0 END)
FROM tb
GROUP BY Name
Ⅳ SQL 怎么把横向数据变成竖向数据
随缘写法···可能有更精简的,我这就赶着想赶着写的 你看看能看懂不,如果觉得对不懂可以联系我
select
nn.客户 客户,
nn.昵称 昵称,
nn.补单日期1 补单日期1,
nn.业务员1 业务员1,
nn.补单日期2 补单日期2,
nn.业务员2 业务员2,
nn.补单日期3 补单日期3,
nn.业务员3 业务员3,
nn.补单日期4 补单日期4,
nn.业务员4 业务员4,
nn.业务员1 首选业务员,
nn.业务员2||'-'||nn.业务员3||'-'||nn.业务员4 候选业务员
from (
select tt.a2 客户,tt.a3 昵称,wm_concat (case when tt.top=0 then tt.a0 else '' end) 补单日期1,
wm_concat (case when tt.top=0 then tt.a4 else ''end) 业务员1,
wm_concat (case when tt.top=1 then tt.a0 else ''end) 补单日期2,
wm_concat (case when tt.top=1 then tt.a4 else ''end) 业务员2,
wm_concat (case when tt.top=2 then tt.a0 else ''end) 补单日期3,
wm_concat (case when tt.top=2 then tt.a4 else ''end) 业务员3,
wm_concat (case when tt.top=3 then tt.a0 else''end) 补单日期4,
wm_concat (case when tt.top=3 then tt.a4 else ''end) 业务员4
from
(
select zz.* from
(
select a.*,(select count(1) from a a1 where a1.a2=a.a2 and a.a0<a1.a0) top from a ORDER BY A2,A0 DESC
) zz
where
zz.top<4
) tt group by tt.a2,tt.a3
) nn
Ⅳ 一张收款表,SQL数据横列变竖列
可以先
select 一下 插入临时表 做个汇总
例如:
select sum(要汇总的字段) as 字段名 into #临时表 from 表名
然后再 按 行转列的方法 转换
http://blog.sina.com.cn/s/blog_4cca663f0100abfv.html
这里有 很详细的 方法 看看吧
Ⅵ 动态Sql语句实现横表转竖表,成绩转成列
select @sql1 = @sql1 + ' , max(case CouName when ''' + CouName + ''' then Score else NULL end) 这里写错了,应该是
select @sql1 = @sql1 + ' , max(case when CouName =''' + CouName + ''' then Score else NULL end) CouName
然后后面少了group by 学号,姓名行转列后面一定要把不转的列group 出来
Ⅶ Sql语句查询问题,如何将横排的数据变为竖排
select*from
(
select PartNO , Year,Month='Jan' , Result = Jan from tb1
unionall
select PartNO , Year,Month ='Feb' , Result = Feb from tb1
unionall
select PartNO , Year,Month='Mar' , Result = Mar from tb1
) t
orderby PartNO, case Month when'Jan' then1when'Feb'then 2 when'Mar' then3 end
Ⅷ 在sql里,如何将横向数据改成纵向数据结构
您好,行列转换等经典SQL语句
参考资料:http://blog.csdn.net/kiki113/archive/2009/04/24/4105929.aspx
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查询横转竖显示
--建立测试数据
create table tb1
(
id varchar(20) not null,
value varchar(20) not null
)
go
insert into tb1
select '1','aa'
union all
select '1','bb'
union all
select '2','aaa'
go
--由于你这表里没有主健,可以用来做标识用,可以先生成一个临时表,并加上自增字段px用来做唯一标识列
select px=IDENTITY(INT,1,1),id,value
INTO #temptb
from tb1
go
select * from #temptb
go
--动态SQL
declare @sql varchar(8000)
set @sql = 'select'
select @sql = @sql + ',max(case px when ' +CONVERT(varchar(4),px)+ ' then value else '''' end) [' + id + ']'
from (select * from #temptb) a
set @sql = STUFF(@sql,7,1,' ') + ' from #temptb'
exec(@sql)
go
--静态SQL
select max(case px when 1 then value else '' end) [1],
max(case px when 2 then value else '' end) [1],
max(case px when 3 then value else '' end) [2]
from #temptb
go
--删除测试数据
DROP TABLE #temptb
go
DROP TABLE tb1
返回:
(所影响的行数为 3 行)
(所影响的行数为 3 行)
px id value
1 1 aa
2 1 bb
3 2 aaa
(所影响的行数为 3 行)
1 1 2
aa bb aaa
1 1 2
aa bb aaa
(所影响的行数为 1 行)