如何把多行数据合并成一行?

时间:2022-07-18 15:04:50
sql2k, 我想把以下数据过滤,然后合并成一行,寻求最优的方法。
declare @t table(a varchar(30), b varchar(30), c varchar(30), d varchar(30))
insert into @t select '1' , '', '', ''
insert into @t select '' , '2', '', ''
insert into @t select '1' , '', '3', '4'
insert into @t select '' , '', '', '4'
insert into @t select '' , '', '2', ''
insert into @t select 'x' , '', '2', ''
insert into @t select '' , 'y', '2', ''
insert into @t select '' , 'y', '2', 'z'

--显示的原始数据
select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
select a,b,c,d from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')

--想得到这个效果,即打扁成一行
select a='1', b='2', c='3', d='4'

15 个解决方案

#1


参考:

create table tb(col varchar(20))
insert tb values ('a')
insert tb values ('b')
insert tb values ('c')
insert tb values ('d')
insert tb values ('e')
go

--方法一
declare @sql varchar(1000)
set @sql = ''
select @sql = @sql + t.col + ',' from (select col from tb) as t
set @sql='select result = ''' + left(@sql , len(@sql) - 1) + ''''
exec(@sql)
/*
result     
---------- 
a,b,c,d,e,
*/

--方法二
declare @output varchar(8000)
select @output = coalesce(@output + ',' , '') + col from tb
print @output
/*
a,b,c,d,e
*/

drop table tb

#2


		declare @t table(a varchar(30), b varchar(30), c varchar(30), d varchar(30))
insert into @t select '1' , '', '', ''
insert into @t select '' , '2', '', ''
insert into @t select '1' , '', '3', '4'
insert into @t select '' , '', '', '4'
insert into @t select '' , '', '2', ''
insert into @t select 'x' , '', '2', ''
insert into @t select '' , 'y', '2', ''
insert into @t select '' , 'y', '2', 'z'

--显示的原始数据
select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
select max(a) as a,max(b) as b,max(c) as c,max(d) as d from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')

#3



declare @t table(a varchar(30), b varchar(30), c varchar(30), d varchar(30))
insert into @t select '1' , '', '', ''
insert into @t select '' , '2', '', ''
insert into @t select '1' , '', '3', '4'
insert into @t select '' , '', '', '4'
insert into @t select '' , '', '2', ''
insert into @t select 'x' , '', '2', ''
insert into @t select '' , 'y', '2', ''
insert into @t select '' , 'y', '2', 'z'

--显示的原始数据
select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
select a,b,c,d from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')

--想得到这个效果,即打扁成一行
select a='1', b='2', c='3', d='4'

select max(a),max(b),max(c),max(d) from (
select a,b,c,d from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')
)t

#4


declare @t table(a varchar(30), b varchar(30), c varchar(30), d varchar(30))
insert into @t select '1' , '', '', ''
insert into @t select '' , '2', '', ''
insert into @t select '1' , '', '3', '4'
insert into @t select '' , '', '', '4'
insert into @t select '' , '', '2', ''
insert into @t select 'x' , '', '2', ''
insert into @t select '' , 'y', '2', ''
insert into @t select '' , 'y', '2', 'z'

--显示的原始数据
--select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
 
select a=max(a),b=max(b),c=max(c),d=max(d) from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')


a                              b                              c                              d
------------------------------ ------------------------------ ------------------------------ ------------------------------
1                              2                              3                              4

(1 行受影响)

#5


字段名全加上MAX就行了

#6


哦,问题弄错了。
abcd只是字段的主键,我要的是取符合主键条件的值,如果哪个主键为空,就拿空主键对应的值。
具体怎么用例子在这表达暂时还没想出来。

我的表格结构大概是:
[窗体名,网格名,列名,列标题,列宽,是否显示]
其中前三列是主键,后三列是设定值。

我是想如果没有合适的主键,
就取[网格名+列名],
如果[网格名+列名]也没有,则取[列名]。

#7


应该这样表达,还需再过滤一下,我要的就是那最后四行(即字段取唯一,其它主键可有可空),
暂时还没想出在结果中怎么剔除前三行(所面有存在的字段)的方法:
declare @t table(frm varchar(30), grd varchar(30), col varchar(30), text varchar(30), width varchar(30))
insert into @t select 'f1', '', 'c1', 's1', '100'
insert into @t select '', 'g1', 'c1', 's2', '200'
insert into @t select '', '', 'c2', 's2', '100'
insert into @t select '', 'g1', 'c2', 's2', '100'
insert into @t select 'f1', 'g2', 'c1', 's1', '200'
insert into @t select '', '', 'c1', 's3', '100'
insert into @t select 'f1', 'g1', 'c1', 's1', '200'
insert into @t select '', '', 'c5', 's3', '100'
insert into @t select '', '', 'c3', 's2', '200'
insert into @t select 'f1', 'g3', '', 's1', '100'

--显示的原始数据
select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
select 
max(frm) as frm,
max(grd) as grd, 
col,
text, width
from @t
where 1=1
and (frm='f1' or frm='')
and (grd='g1' or grd='')
group by col, text, width
order by col, grd, frm

#8


现在可以获得我所需要的数据了,目前得出的是一个网格(grd)的列(col)信息。
如果再扩展一下,一次性把整个窗体(frm)中所有网格的列信息显示出来的话,好像有冲突,
到时在前台代码中不好过滤(如下选用后面标有“2222”的语句时所得的结果)。
declare @t table(frm varchar(30), grd varchar(30), col varchar(30), text varchar(30), width varchar(30))
insert into @t select 'f1', '', 'c1', 's11', '100'
insert into @t select '', 'g1', 'c1', 's12', '200'
insert into @t select '', '', 'c2', 's21', '300'
insert into @t select '', 'g1', 'c2', 's22', '400'
insert into @t select 'f1', 'g2', 'c1', 's13', '500'
insert into @t select '', '', 'c1', 's14', '600'
insert into @t select 'f1', 'g1', 'c1', 's15', '700'
insert into @t select '', '', 'c5', 's51', '800'
insert into @t select '', '', 'c3', 's31', '900'
insert into @t select 'f1', 'g3', '', 's16', '000'

--显示的原始数据
select * from @t

--
declare @t2 table(id int identity(1,1), frm varchar(30), grd varchar(30), col varchar(30), text varchar(30), width varchar(30))
insert into @t2(frm, grd, col, text, width)
select 
max(frm) as frm,
max(grd) as grd, 
col,
text, width
from @t
where 1=1
and (frm='f1' or frm='')
and (grd='g1' or grd='') --1111
-- --and (grd='g1' or grd='') --2222
group by col, text, width
order by col, grd, frm

select * from @t2 where id in(
select max(id) from @t2 group by col --1111
--select max(id) from @t2 group by col,grd --2222
)

#9


学习一下……

#10


我也学习一下。。。。

#11


楼主要想要什么结果贴出来

#12


最好给出完整的表结构,测试数据,计算方法和正确结果.否则耽搁的是你宝贵的时间。
如果有多表,表之间如何关联?


发帖注意事项
http://topic.csdn.net/u/20091130/21/fb718680-98ff-4afb-98d8-cff2f8293ed5.html?24281

#13


每天回复可得可用分耶。。。。。。。。。。。。。。。。。。。。。。

#14


楼住可以去搜索一下,行列转换就可以

#15


不明白!
是行转列吗?

#1


参考:

create table tb(col varchar(20))
insert tb values ('a')
insert tb values ('b')
insert tb values ('c')
insert tb values ('d')
insert tb values ('e')
go

--方法一
declare @sql varchar(1000)
set @sql = ''
select @sql = @sql + t.col + ',' from (select col from tb) as t
set @sql='select result = ''' + left(@sql , len(@sql) - 1) + ''''
exec(@sql)
/*
result     
---------- 
a,b,c,d,e,
*/

--方法二
declare @output varchar(8000)
select @output = coalesce(@output + ',' , '') + col from tb
print @output
/*
a,b,c,d,e
*/

drop table tb

#2


		declare @t table(a varchar(30), b varchar(30), c varchar(30), d varchar(30))
insert into @t select '1' , '', '', ''
insert into @t select '' , '2', '', ''
insert into @t select '1' , '', '3', '4'
insert into @t select '' , '', '', '4'
insert into @t select '' , '', '2', ''
insert into @t select 'x' , '', '2', ''
insert into @t select '' , 'y', '2', ''
insert into @t select '' , 'y', '2', 'z'

--显示的原始数据
select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
select max(a) as a,max(b) as b,max(c) as c,max(d) as d from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')

#3



declare @t table(a varchar(30), b varchar(30), c varchar(30), d varchar(30))
insert into @t select '1' , '', '', ''
insert into @t select '' , '2', '', ''
insert into @t select '1' , '', '3', '4'
insert into @t select '' , '', '', '4'
insert into @t select '' , '', '2', ''
insert into @t select 'x' , '', '2', ''
insert into @t select '' , 'y', '2', ''
insert into @t select '' , 'y', '2', 'z'

--显示的原始数据
select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
select a,b,c,d from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')

--想得到这个效果,即打扁成一行
select a='1', b='2', c='3', d='4'

select max(a),max(b),max(c),max(d) from (
select a,b,c,d from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')
)t

#4


declare @t table(a varchar(30), b varchar(30), c varchar(30), d varchar(30))
insert into @t select '1' , '', '', ''
insert into @t select '' , '2', '', ''
insert into @t select '1' , '', '3', '4'
insert into @t select '' , '', '', '4'
insert into @t select '' , '', '2', ''
insert into @t select 'x' , '', '2', ''
insert into @t select '' , 'y', '2', ''
insert into @t select '' , 'y', '2', 'z'

--显示的原始数据
--select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
 
select a=max(a),b=max(b),c=max(c),d=max(d) from @t
where 1=1
and (a='1' or a='')
and (b='2' or b='')
and (c='3' or c='')
and (d='4' or d='')


a                              b                              c                              d
------------------------------ ------------------------------ ------------------------------ ------------------------------
1                              2                              3                              4

(1 行受影响)

#5


字段名全加上MAX就行了

#6


哦,问题弄错了。
abcd只是字段的主键,我要的是取符合主键条件的值,如果哪个主键为空,就拿空主键对应的值。
具体怎么用例子在这表达暂时还没想出来。

我的表格结构大概是:
[窗体名,网格名,列名,列标题,列宽,是否显示]
其中前三列是主键,后三列是设定值。

我是想如果没有合适的主键,
就取[网格名+列名],
如果[网格名+列名]也没有,则取[列名]。

#7


应该这样表达,还需再过滤一下,我要的就是那最后四行(即字段取唯一,其它主键可有可空),
暂时还没想出在结果中怎么剔除前三行(所面有存在的字段)的方法:
declare @t table(frm varchar(30), grd varchar(30), col varchar(30), text varchar(30), width varchar(30))
insert into @t select 'f1', '', 'c1', 's1', '100'
insert into @t select '', 'g1', 'c1', 's2', '200'
insert into @t select '', '', 'c2', 's2', '100'
insert into @t select '', 'g1', 'c2', 's2', '100'
insert into @t select 'f1', 'g2', 'c1', 's1', '200'
insert into @t select '', '', 'c1', 's3', '100'
insert into @t select 'f1', 'g1', 'c1', 's1', '200'
insert into @t select '', '', 'c5', 's3', '100'
insert into @t select '', '', 'c3', 's2', '200'
insert into @t select 'f1', 'g3', '', 's1', '100'

--显示的原始数据
select * from @t

--这些是我过滤出来的数据,只是里边有很多的空格
select 
max(frm) as frm,
max(grd) as grd, 
col,
text, width
from @t
where 1=1
and (frm='f1' or frm='')
and (grd='g1' or grd='')
group by col, text, width
order by col, grd, frm

#8


现在可以获得我所需要的数据了,目前得出的是一个网格(grd)的列(col)信息。
如果再扩展一下,一次性把整个窗体(frm)中所有网格的列信息显示出来的话,好像有冲突,
到时在前台代码中不好过滤(如下选用后面标有“2222”的语句时所得的结果)。
declare @t table(frm varchar(30), grd varchar(30), col varchar(30), text varchar(30), width varchar(30))
insert into @t select 'f1', '', 'c1', 's11', '100'
insert into @t select '', 'g1', 'c1', 's12', '200'
insert into @t select '', '', 'c2', 's21', '300'
insert into @t select '', 'g1', 'c2', 's22', '400'
insert into @t select 'f1', 'g2', 'c1', 's13', '500'
insert into @t select '', '', 'c1', 's14', '600'
insert into @t select 'f1', 'g1', 'c1', 's15', '700'
insert into @t select '', '', 'c5', 's51', '800'
insert into @t select '', '', 'c3', 's31', '900'
insert into @t select 'f1', 'g3', '', 's16', '000'

--显示的原始数据
select * from @t

--
declare @t2 table(id int identity(1,1), frm varchar(30), grd varchar(30), col varchar(30), text varchar(30), width varchar(30))
insert into @t2(frm, grd, col, text, width)
select 
max(frm) as frm,
max(grd) as grd, 
col,
text, width
from @t
where 1=1
and (frm='f1' or frm='')
and (grd='g1' or grd='') --1111
-- --and (grd='g1' or grd='') --2222
group by col, text, width
order by col, grd, frm

select * from @t2 where id in(
select max(id) from @t2 group by col --1111
--select max(id) from @t2 group by col,grd --2222
)

#9


学习一下……

#10


我也学习一下。。。。

#11


楼主要想要什么结果贴出来

#12


最好给出完整的表结构,测试数据,计算方法和正确结果.否则耽搁的是你宝贵的时间。
如果有多表,表之间如何关联?


发帖注意事项
http://topic.csdn.net/u/20091130/21/fb718680-98ff-4afb-98d8-cff2f8293ed5.html?24281

#13


每天回复可得可用分耶。。。。。。。。。。。。。。。。。。。。。。

#14


楼住可以去搜索一下,行列转换就可以

#15


不明白!
是行转列吗?