sql纵向
① 在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横向+纵向合并
没有表结构,不清楚写的对不对,用了sum()over(),这是Oracle的用法,其他数据库能不能用就不清楚了,以下是代码
selectrownumas序号,a.*
from(selectdistincta.名称as医嘱名称,
zlspellcode(a.名称)as简码,
e.类别,
b.检查部位,
b.检查方法,
c.名称as收费名称,
c.标识主码,
b.收费数量as数量,
d.现价as价格,
c.站点,
dECOdE(A.撤档时间,
to_date('3000-01-01','YYYY-MM-dd'),
NULL,
null,
null,
'√')AS是否停用,
sum(b.收费数量*d.现价)over()as价格
from诊疗项目目录a,
诊疗收费关系b,
收费项目目录c,
收费价目d,
收费类别e
wherea.Id=b.诊疗项目Id
ANdb.收费项目Id=c.id
andc.Id=d.收费细目Id
anda.类别=e.编码
anda.撤档时间=to_date('3000-01-01','yyyy-mm-dd')
andd.终止日期=to_date('3000-01-01','yyyy-mm-dd')
anda.类别[0]
anda.服务对象=[1]
---orderbya.名称
)a
wherea.是否停用isnull
orderby序号
③ SQL如何将两个列数不一样的表的内容纵向拼接在一起
一句sql还是比较难办到的。可以用存储过程,先新建一张有九列新表,把表A中数据select出来插入新表中,再把表B中数据查询出来并补上三个空字段后插入新表。这样新表就有表A+表B纵向拼接的效果了。
④ 怎样用sql把一个数据集纵向截成三段然后横向连接
这个数据集是我用别的方法做的
data means_2 (drop=Group);
merge means_1 (where=(group="A") rename=(age=GroupA))
means_1 (where=(group="B") rename=(age=GroupB))
means_1 (where=(group="C") rename=(age=Total)) ;
run ;
复制代码
自己编了一个sql的版本,第一个数据集是means—1
proc sql ;
create table work.means_2 as
select means_1.*
from work.means_1 (where=(group="A"))
full join work.means_1 (where=(group="B"))
on means_1._STAT_=means
⑤ SQL SERVER中纵向的数据横向显示出来
create TABLE Table1 (Name varchar(50),Subject varchar(50))
INSERT INTO TABLE1 VALUES('A','a1')
INSERT INTO TABLE1 VALUES('A','a2')
INSERT INTO TABLE1 VALUES('A','a3')
INSERT INTO TABLE1 VALUES('A','a4')
INSERT INTO TABLE1 VALUES('A','a5')
INSERT INTO TABLE1 VALUES('A','a6')
INSERT INTO TABLE1 VALUES('A','a7')
INSERT INTO TABLE1 VALUES('B','b1')
INSERT INTO TABLE1 VALUES('B','b2')
INSERT INTO TABLE1 VALUES('B','b3')
INSERT INTO TABLE1 VALUES('B','b4')
INSERT INTO TABLE1 VALUES('B','b5')
INSERT INTO TABLE1 VALUES('B','b11')
INSERT INTO TABLE1 VALUES('B','b23')
INSERT INTO TABLE1 VALUES('B','b34')
INSERT INTO TABLE1 VALUES('B','b8')
INSERT INTO TABLE1 VALUES('B','b9')
INSERT INTO TABLE1 VALUES('B','b15')
就生成了表单TABLE1,如果把公司名称A,B横向输出,Subject的话,比较简单的是把Subject显示在1列,里面元素用","隔开,如果分列显示,就要找到Subject最长的列,否则影响效率;
因为不知道你的参数最多是多少,所以就在1列中显示.
可以写一个函数F_str
create function F_str(@name varchar)
returns nvarchar(100)
as
begin
declare @S nvarchar(100)
select @S=isnull(@S+',','')+Subject from table1 where Name=@name
return @S
end
生成函数后在调用即可:
select distinct Name,Subject=dbo.F_str(Name) from Table1
自己用的话注意每次实验删除函数,不然创建2次重名的函数是不可以的
因为我的Name是动态读取的,不管多少公司,都是没问题的,唯一的不同就是
产品显示出来是在一列当中,而不是分列显示,不知道满足你的需求吗.
Name Subject
A a1,a2,a3.....
B b1,b2,b3.....
C c1,c2,c3.....
... .....
这种格式的,Subject是不分列的,在一列.
要是需要分列的话,实现比较麻烦,需要的话,和我说.
declare @c int,@sql varchar(5000)
set @c=(select max(a) from (select count(*)a from table1 group by name)b)
declare @i int
set @i=1
select x=@c,y='列'+cast(@c as varchar) into #temp
while @i<@c
begin
insert into #temp values(@i,'列'+cast(@i as varchar))
set @i=@i+1
end
select y,name,subject into #temp2 from #temp t left join (select ROW_NUMBER() over(PARTITION BY name order by name) as id,name,subject from table1 ) tb on tb.id=t.x
set @sql = 'select name'
select @sql = @sql + ' , max(case y when ''' + y + ''' then subject else null end )[' + y + ']'
from (select distinct y from #temp2 ) as a
set @sql = @sql + ' from #temp2 group by name'
exec(@sql)
drop table #temp
drop table #temp2
SQL2005可以用,2000估计不能用,2000函数不全
⑥ sql多表联合查询纵向数据
不知道 不过你可以先用vfp 添加表单后,看看里面的sql语句是怎么写的。
我的电脑没有装vfp 要比可以帮你试一下。
⑦ SQL 将横向数据转为纵向记录
使用union连接SQL语句,可以实现常见的SQL行转列运用。
以图中表格为例:
需要注意,如果有需要显示重复记录,把union 改成 union all
⑧ sql server多表纵向拼表查询,怎么批量处理
可以拼凑SQL语句,然后用exec执行字符串。
祝好运,望采纳。