怎么把记录集中的多条相同的记录合并成一条记录

jjonline 2008-01-04 10:48:33
例如:
表table

a, b, c
-------
111,2,3
111,2,4
111,3,3
111,3,4
222,2,3
222,2,4
222,3,3
222,3,4

合并成

a, b,c,d
---------
111,2,3,4
111,3,3,4
222,2,3,4
222,3,3,4
...全文
1783 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdlpy 2008-01-09
  • 打赏
  • 举报
回复
真强,服了!
wuliangbo 2008-01-09
  • 打赏
  • 举报
回复
嗯。有用
rishengw 2008-01-08
  • 打赏
  • 举报
回复
进来学习一下
Tomcat4 2008-01-08
  • 打赏
  • 举报
回复
强悍,收藏!
-狙击手- 2008-01-04
  • 打赏
  • 举报
回复
BS龟,你星那多,不能坐那儿息息呀
jjonline 2008-01-04
  • 打赏
  • 举报
回复
哈哈!果然是一样的!谢谢啦!!

dawugui 非常感谢你啊!

呵呵!你太强大了


happyflystone 也非常感谢你啊!

嘎嘎!你太实用了!
-狙击手- 2008-01-04
  • 打赏
  • 举报
回复
呵呵!假如 C字段不是整型值呢!
而是时间类型呢?

---

一样使用
dawugui 2008-01-04
  • 打赏
  • 举报
回复
/*
普通行列转换
(爱新觉罗.毓华 2007-11-18于海南三亚)

假设有张学生成绩表(tb)如下:
Name Subject Result
张三 语文  74
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94
*/

-------------------------------------------------------------------------
/*
想变成
姓名 语文 数学 物理
---------- ----------- ----------- -----------
李四 74 84 94
张三 74 83 93
*/

create table tb
(
Name varchar(10) ,
Subject varchar(10) ,
Result int
)

insert into tb(Name , Subject , Result) values('张三' , '语文' , 74)
insert into tb(Name , Subject , Result) values('张三' , '数学' , 83)
insert into tb(Name , Subject , Result) values('张三' , '物理' , 93)
insert into tb(Name , Subject , Result) values('李四' , '语文' , 74)
insert into tb(Name , Subject , Result) values('李四' , '数学' , 84)
insert into tb(Name , Subject , Result) values('李四' , '物理' , 94)
go

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
max(case subject when '语文' then result else 0 end) 语文,
max(case subject when '数学' then result else 0 end) 数学,
max(case subject when '物理' then result else 0 end) 物理
from tb
group by name
/*
姓名 语文 数学 物理
---------- ----------- ----------- -----------
李四 74 84 94
张三 74 83 93
*/

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare @sql varchar(8000)
set @sql = 'select Name as ' + '姓名'
select @sql = @sql + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct Subject from tb) as a
set @sql = @sql + ' from tb group by name'
exec(@sql)
/*
姓名 数学 物理 语文
---------- ----------- ----------- -----------
李四 84 94 74
张三 83 93 74
*/

-------------------------------------------------------------------
/*加个平均分,总分
姓名 语文 数学 物理 平均分 总分
---------- ----------- ----------- ----------- -------------------- -----------
李四 74 84 94 84.00 252
张三 74 83 93 83.33 250
*/

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
max(case subject when '语文' then result else 0 end) 语文,
max(case subject when '数学' then result else 0 end) 数学,
max(case subject when '物理' then result else 0 end) 物理,
cast(avg(result*1.0) as decimal(18,2)) 平均分,
sum(result) 总分
from tb
group by name
/*
姓名 语文 数学 物理 平均分 总分
---------- ----------- ----------- ----------- -------------------- -----------
李四 74 84 94 84.00 252
张三 74 83 93 83.33 250
*/

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare @sql1 varchar(8000)
set @sql1 = 'select Name as ' + '姓名'
select @sql1 = @sql1 + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct Subject from tb) as a
set @sql1 = @sql1 + ' , cast(avg(result*1.0) as decimal(18,2)) 平均分,sum(result) 总分 from tb group by name'
exec(@sql1)
/*
姓名 数学 物理 语文 平均分 总分
---------- ----------- ----------- ----------- -------------------- -----------
李四 84 94 74 84.00 252
张三 83 93 74 83.33 250
*/

drop table tb

---------------------------------------------------------
---------------------------------------------------------
/*
如果上述两表互相换一下:即

姓名 语文 数学 物理
张三 74  83  93
李四 74  84  94

想变成
Name Subject Result
---------- ------- -----------
李四 语文 74
李四 数学 84
李四 物理 94
张三 语文 74
张三 数学 83
张三 物理 93
*/

create table tb1
(
姓名 varchar(10) ,
语文 int ,
数学 int ,
物理 int
)

insert into tb1(姓名 , 语文 , 数学 , 物理) values('张三',74,83,93)
insert into tb1(姓名 , 语文 , 数学 , 物理) values('李四',74,84,94)

select * from
(
select 姓名 as Name , Subject = '语文' , Result = 语文 from tb1
union all
select 姓名 as Name , Subject = '数学' , Result = 数学 from tb1
union all
select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1
) t
order by name , case Subject when '语文' then 1 when '数学' then 2 when '物理' then 3 when '总分' then 4 end

--------------------------------------------------------------------
/*加个平均分,总分
Name Subject Result
---------- ------- --------------------
李四 语文 74.00
李四 数学 84.00
李四 物理 94.00
李四 平均分 84.00
李四 总分 252.00
张三 语文 74.00
张三 数学 83.00
张三 物理 93.00
张三 平均分 83.33
张三 总分 250.00
*/

select * from
(
select 姓名 as Name , Subject = '语文' , Result = 语文 from tb1
union all
select 姓名 as Name , Subject = '数学' , Result = 数学 from tb1
union all
select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1
union all
select 姓名 as Name , Subject = '平均分' , Result = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb1
union all
select 姓名 as Name , Subject = '总分' , Result = 语文 + 数学 + 物理 from tb1
) t
order by name , case Subject when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 end

drop table tb1
jjonline 2008-01-04
  • 打赏
  • 举报
回复
呵呵!假如 C字段不是整型值呢!
而是时间类型呢?
-狙击手- 2008-01-04
  • 打赏
  • 举报
回复
create table tb(a int, b int, c int)
insert into tb values(111,2,3)
insert into tb values(111,2,4)
insert into tb values(111,3,3)
insert into tb values(111,3,4)
insert into tb values(222,2,3)
insert into tb values(222,2,4)
insert into tb values(222,3,3)
insert into tb values(222,3,4)
go

select a,b,min(c) as c,max(c) as d
from tb
group by a,b
drop table tb

/*
a b c d
----------- ----------- ----------- -----------
111 2 3 4
222 2 3 4
111 3 3 4
222 3 3 4

(所影响的行数为 4 行)
*/
jjonline 2008-01-04
  • 打赏
  • 举报
回复
中间可能是N个的呀!

不能固定死是 3,或者4的呀!

例如:
表table

a, b, c 3个字段
-------
111,2,3
111,2,4
111,2,5
111,3,3
111,3,4
111,3,5
111,3,6

222,2,3
222,2,4
222,2,5
222,2,6

222,3,3
222,3,4
222,3,5
222,3,6

合并成

a, b, c, d 4个字段
---------
111,2,3,6
111,3,3,6
222,2,3,6
222,3,3,6

取最后一个的
dawugui 2008-01-04
  • 打赏
  • 举报
回复
create table tb(a int, b int, c int)
insert into tb values(111,2,3)
insert into tb values(111,2,4)
insert into tb values(111,3,3)
insert into tb values(111,3,4)
insert into tb values(222,2,3)
insert into tb values(222,2,4)
insert into tb values(222,3,3)
insert into tb values(222,3,4)
go
--静态SQL,指C固定为3,4
select a,b,
max(case c when 3 then c else 0 end) [c],
max(case c when 4 then c else 0 end) [d]
from tb
group by a,b

/*
a b c d
----------- ----------- ----------- -----------
111 2 3 4
222 2 3 4
111 3 3 4
222 3 3 4

(4 行受影响)
*/

--动态SQL,指C不固定。
declare @sql varchar(8000)
set @sql = 'select a,b'
select @sql = @sql + ' , max(case C when ''' + cast(C as varchar) + ''' then C else 0 end) [' + cast(C as varchar) + ']'
from (select distinct C from tb) as a
set @sql = @sql + ' from tb group by a , b'
exec(@sql)
/*
a b 3 4
----------- ----------- ----------- -----------
111 2 3 4
222 2 3 4
111 3 3 4
222 3 3 4

(4 行受影响)
*/
drop table tb
dawugui 2008-01-04
  • 打赏
  • 举报
回复
create table tb(a int, b int, c int)
insert into tb values(111,2,3)
insert into tb values(111,2,4)
insert into tb values(111,3,3)
insert into tb values(111,3,4)
insert into tb values(222,2,3)
insert into tb values(222,2,4)
insert into tb values(222,3,3)
insert into tb values(222,3,4)
go

select a,b,
max(case c when 3 then c else 0 end) [c],
max(case c when 4 then c else 0 end) [d]
from tb
group by a,b

drop table tb

/*
a b c d
----------- ----------- ----------- -----------
111 2 3 4
222 2 3 4
111 3 3 4
222 3 3 4

(4 行受影响)
*/
jjonline 2008-01-04
  • 打赏
  • 举报
回复
例如:
表table

a, b, c 3个字段
-------
111,2,3
111,2,4
111,2,5
111,3,3
111,3,4
111,3,5
222,2,3
222,2,4
222,2,5
222,3,3
222,3,4
222,3,5

合并成

a, b, c, d 4个字段
---------
111,2,3,5
111,3,3,5
222,2,3,5
222,3,3,5
jjonline 2008-01-04
  • 打赏
  • 举报
回复
我意思是合并后多了一个字段啊
dawugui 2008-01-04
  • 打赏
  • 举报
回复
--sql server 2005写法.
create table tb(a int, b int, c int)
insert into tb values(111,2,3)
insert into tb values(111,2,4)
insert into tb values(111,3,3)
insert into tb values(111,3,4)
insert into tb values(222,2,3)
insert into tb values(222,2,4)
insert into tb values(222,3,3)
insert into tb values(222,3,4)
go
SELECT * FROM(SELECT DISTINCT a,b FROM tb)A OUTER APPLY(
SELECT [c]= STUFF(REPLACE(REPLACE(
(
SELECT c FROM tb N
WHERE a = A.a and b = A.b
FOR XML AUTO
), '<N c="', ','), '"/>', ''), 1, 1, '')
)N

drop table tb

/*a b c
----------- ----------- -----
111 2 3,4
111 3 3,4
222 2 3,4
222 3 3,4

(4 行受影响)

*/
dawugui 2008-01-04
  • 打赏
  • 举报
回复
--sql server 2000写法.
create table tb(a int, b int, c int)
insert into tb values(111,2,3)
insert into tb values(111,2,4)
insert into tb values(111,3,3)
insert into tb values(111,3,4)
insert into tb values(222,2,3)
insert into tb values(222,2,4)
insert into tb values(222,3,3)
insert into tb values(222,3,4)
go
--创建一个合并的函数
create function f_hb(@a int , @b int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str = ''
select @str = @str + ',' + cast(c as varchar) from tb where a = @a and b = @b
set @str = right(@str , len(@str) - 1)
return(@str)
End
go

--调用自定义函数得到结果:
select distinct a , b,dbo.f_hb(a , b) as c from tb

drop table tb
drop function f_hb

/*a b c
----------- ----------- -----
111 2 3,4
111 3 3,4
222 2 3,4
222 3 3,4

(4 行受影响)

*/
dawugui 2008-01-04
  • 打赏
  • 举报
回复
合并列值
原著:邹建
改编:爱新觉罗.毓华 2007-12-16 广东深圳

表结构,数据如下:
id value
----- ------
1 aa
1 bb
2 aaa
2 bbb
2 ccc

需要得到结果:
id values
------ -----------
1 aa,bb
2 aaa,bbb,ccc
即:group by id, 求 value 的和(字符串相加)

1. 旧的解决方法(在sql server 2000中只能用函数解决。)
--1. 创建处理函数
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go

CREATE FUNCTION dbo.f_str(@id int)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @r varchar(8000)
SET @r = ''
SELECT @r = @r + ',' + value FROM tb WHERE id=@id
RETURN STUFF(@r, 1, 1, '')
END
GO

-- 调用函数
SELECt id, value = dbo.f_str(id) FROM tb GROUP BY id

drop table tb
drop function dbo.f_str

/*
id value
----------- -----------
1 aa,bb
2 aaa,bbb,ccc
(所影响的行数为 2 行)
*/

--2、另外一种函数.
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go

--创建一个合并的函数
create function f_hb(@id int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str = ''
select @str = @str + ',' + cast(value as varchar) from tb where id = @id
set @str = right(@str , len(@str) - 1)
return(@str)
End
go

--调用自定义函数得到结果:
select distinct id ,dbo.f_hb(id) as value from tb

drop table tb
drop function dbo.f_hb

/*
id value
----------- -----------
1 aa,bb
2 aaa,bbb,ccc
(所影响的行数为 2 行)
*/

2. 新的解决方法(在sql server 2005中用OUTER APPLY等解决。)
create table tb(id int, value varchar(10))
insert into tb values(1, 'aa')
insert into tb values(1, 'bb')
insert into tb values(2, 'aaa')
insert into tb values(2, 'bbb')
insert into tb values(2, 'ccc')
go
-- 查询处理
SELECT * FROM(SELECT DISTINCT id FROM tb)A OUTER APPLY(
SELECT [values]= STUFF(REPLACE(REPLACE(
(
SELECT value FROM tb N
WHERE id = A.id
FOR XML AUTO
), '<N value="', ','), '"/>', ''), 1, 1, '')
)N
drop table tb

/*
id values
----------- -----------
1 aa,bb
2 aaa,bbb,ccc

(2 行受影响)
*/
dawugui 2008-01-04
  • 打赏
  • 举报
回复
/*
带符号合并行列转换(爱新觉罗.毓华 2007-11-19于海南三亚)

有表tb,其数据如下:
a b
1 1
1 2
1 3
2 1
2 2
3 1
如何转换成如下结果:
a b
1 1,2,3
2 1,2
3 1
*/

create table tb
(
a int,
b int
)
insert into tb(a,b) values(1,1)
insert into tb(a,b) values(1,2)
insert into tb(a,b) values(1,3)
insert into tb(a,b) values(2,1)
insert into tb(a,b) values(2,2)
insert into tb(a,b) values(3,1)
go

--创建一个合并的函数
create function f_hb(@a int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str = ''
select @str = @str + ',' + cast(b as varchar) from tb where a = @a
set @str = right(@str , len(@str) - 1)
return(@str)
End
go

--调用自定义函数得到结果:
select distinct a ,dbo.f_hb(a) as b from tb

drop table tb
drop function f_hb

/*
结果
a b
----------- ------
1 1,2,3
2 1,2
3 1

(所影响的行数为 3 行)
*/

----------------------------------------------------
/*
多个前列的合并
数据的原始状态如下:
ID PR CON OP SC
001 p c 差 6
001 p c 好 2
001 p c 一般 4
002 w e 差 8
002 w e 好 7
002 w e 一般 1
用SQL语句实现,变成如下的数据
ID PR CON OPS
001 p c 差(6),好(2),一般(4)
002 w e 差(8),好(7),一般(1)
*/

create table tb
(
id varchar(10),
pr varchar(10),
con varchar(10),
op varchar(10),
sc int
)

insert into tb(ID,PR,CON,OP,SC) values('001', 'p', 'c', '差', 6)
insert into tb(ID,PR,CON,OP,SC) values('001', 'p', 'c', '好', 2)
insert into tb(ID,PR,CON,OP,SC) values('001', 'p', 'c', '一般', 4)
insert into tb(ID,PR,CON,OP,SC) values('002', 'w', 'e', '差', 8)
insert into tb(ID,PR,CON,OP,SC) values('002', 'w', 'e', '好', 7)
insert into tb(ID,PR,CON,OP,SC) values('002', 'w', 'e', '一般', 1)
go

--创建一个合并的函数
create function f_hb(@id varchar(10) , @pr varchar(10) , @con varchar(10))
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str = ''
select @str = @str + ',' + cast(OP as varchar) + '('
+ cast(sc as varchar) + ')'
from tb where id = @id and @pr = pr and @con = con
set @str = right(@str , len(@str) - 1)
return(@str)
End
go

--调用自定义函数得到结果:
select distinct id , pr , con , dbo.f_hb(id,pr,con) as ops from tb

drop table tb
drop function f_hb

/*
结果
id pr con ops
---------- ---------- ---------- ------------------
001 p c 差(6),好(2),一般(4)
002 w e 差(8),好(7),一般(1)

(所影响的行数为 2 行)
*/

----------------------------------------------------
/*如何将一列中所有的值一行显示
数据源
a
b
c
d
e
结果
a,b,c,d,e
*/

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 = ''' + @sql + ''''
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

34,575

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧