SQL字段叠加问题?

昔梦无痕 2009-05-22 02:24:11
现在又表中2字段:
username accessories
A 附件1,附件2,,附件3,,
A 附件4,,附件5,附件6,,
A 附件7,附件8,,附件9,,
B 附件1,,附件2,附件3,,
B 附件4,,附件5,附件6,,
B 附件7,附件8,,附件9,,

现在要查询,同一个用户,上传了多少附件,每个数组键值算一个,空的不算,也就是说
查询出来需要时这样:
username accesscount
A 附件1,附件2,附件3,附件4,附件5,附件6,附件7,附件8,附件9
B 附件1,附件2,附件3,附件4,附件5,附件6,附件7,附件8,附件9
当然,如果能将后面的数组个数也给计算出来更好,如下:
username accesscount
A 9
B 9
谢谢各位大侠了。。。。。。
...全文
184 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
AppleBBS 2010-06-01
  • 打赏
  • 举报
回复
强汗 太牛了
等不到来世 2009-05-22
  • 打赏
  • 举报
回复
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([username] varchar(1),[accessories] varchar(20))
insert [tb]
select 'A','附件1,附件2,,附件3,,' union all
select 'A','附件4,,附件5,附件6,,' union all
select 'A','附件7,附件8,,附件9,,' union all
select 'B','附件1,,附件2,附件3,,' union all
select 'B','附件4,,附件5,附件6,,' union all
select 'B','附件7,附件8,,附件9,,'
go
--select * from [tb]

select username,accessories=left(accessories,len(accessories)-1)
from
(
select username,accessories=(select replace(accessories,',,',',') from tb where username=t.username for xml path(''))
from tb t
group by username
) tt
/*
username accessories
-------- ---------------------------------------------------------
A 附件1,附件2,附件3,附件4,附件5,附件6,附件7,附件8,附件9
B 附件1,附件2,附件3,附件4,附件5,附件6,附件7,附件8,附件9

(2 行受影响)
*/
JonasFeng 2009-05-22
  • 打赏
  • 举报
回复
楼主,这已经是比较简单的方法了。

利用SQL2005的新特性才完成。
如果用SQL2000.则要考虑临时表了。
JonasFeng 2009-05-22
  • 打赏
  • 举报
回复
-- 测试数据
IF OBJECT_ID('LI') IS NOT NULL
DROP TABLE LI

CREATE TABLE LI (username varchar(10), accessories varchar(50))
INSERT LI SELECT 'A', '附件1,附件2,附件3,'
UNION ALL SELECT 'A', '附件4,附件5,附件6,'
UNION ALL SELECT 'A', '附件7,附件8,附件9,'
UNION ALL SELECT 'B', '附件1,附件2,附件3,'
UNION ALL SELECT 'B', '附件4,附件5,附件6,'
UNION ALL SELECT 'B', '附件7,附件8,附件9,'

--楼主要求1(合并数据)
SELECT *
FROM(
SELECT DISTINCT username
FROM LI
)A
OUTER APPLY(
SELECT
[accessoriesList]= STUFF(REPLACE(REPLACE(
(
SELECT [accessories] FROM LI N
WHERE [username] = A.username
FOR XML AUTO
), '<N accessories="', ','), '"/>', ''), 1, 1, '')
)N



--楼主要求2(计算数组的个数)
select LO.username, COUNT(accessories) AS accesscount
FROM
(
Select
a.username,b.accessories
From
(select username,accessories=convert(xml,'<root><v>'+replace(left(accessories,len(accessories)-1),',','</v><v>')+'</v></root>') from LI)a
outer apply
(select accessories=C.v.value('.','nvarchar(100)') from a.accessories.nodes('/root/v')C(v) )b
) LO
GROUP BY LO.USERNAME


--删除测试数据
DROP TABLE LI

/*
--结果1
username accessoriesList
A 附件1,附件2,附件3,附件4,附件5,附件6,,附件7,附件8,附件9,
B 附件1,附件2,附件3,附件4,附件5,附件6,,附件7,附件8,附件9,

--结果1
username accesscount
A 9
B 9
*/
JonasFeng 2009-05-22
  • 打赏
  • 举报
回复
这样OK了。

-- 测试数据
IF OBJECT_ID('LI') IS NOT NULL
DROP TABLE LI

CREATE TABLE LI (username varchar(10), accessories varchar(50))
INSERT LI SELECT 'A', '附件1,附件2,附件3,'
UNION ALL SELECT 'A', '附件4,附件5,附件6,'
UNION ALL SELECT 'A', '附件7,附件8,附件9,'
UNION ALL SELECT 'B', '附件1,附件2,附件3,'
UNION ALL SELECT 'B', '附件4,附件5,附件6,'
UNION ALL SELECT 'B', '附件7,附件8,附件9,'



-- 查询处理

SELECT *
FROM(
SELECT DISTINCT username
FROM LI
)A
OUTER APPLY(
SELECT
[accessoriesList]= STUFF(REPLACE(REPLACE(
(
SELECT [accessories] FROM LI N
WHERE [username] = A.username
FOR XML AUTO
), '<N accessories="', ','), '"/>', ''), 1, 1, '')
)N


--结果
username accessoriesList
A 附件1,附件2,附件3,附件4,附件5,附件6,,附件7,附件8,附件9,
B 附件1,附件2,附件3,附件4,附件5,附件6,,附件7,附件8,附件9,
昔梦无痕 2009-05-22
  • 打赏
  • 举报
回复

有没有简单点的啊,这样的话,要在我这上面查询肯定慢死,数据量大。
sdhdy 2009-05-22
  • 打赏
  • 举报
回复
楼主参考一下这个:
--******************************************************************************************
-- 合并列值
--*******************************************************************************************
表结构,数据如下:
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中只能用函数解决。)
--=============================================================================
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
--1. 创建处理函数
CREATE FUNCTION dbo.f_strUnite(@id int)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @str varchar(8000)
SET @str = ''
SELECT @str = @str + ',' + value FROM tb WHERE id=@id
RETURN STUFF(@str, 1, 1, '')
END
GO
-- 调用函数
SELECt id, value = dbo.f_strUnite(id) FROM tb GROUP BY id
drop table tb
drop function dbo.f_strUnite
go
/*
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 行受影响)
*/

--SQL2005中的方法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

select id, [values]=stuff((select ','+[value] from tb t where id=tb.id for xml path('')), 1, 1, '')
from tb
group by id

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

(2 row(s) affected)

*/

drop table tb

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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