有一批数据,如下
id name
1 as
1 sa
2 jskh
2 asd
2 asdasd
3 asd
得到如下结果:
1 as,sa
2 jskh,asd,asdasd
3 asd 可以用存储过程,但最好能直接用sql语句不带参数能做到吗?
id name
1 as
1 sa
2 jskh
2 asd
2 asdasd
3 asd
得到如下结果:
1 as,sa
2 jskh,asd,asdasd
3 asd 可以用存储过程,但最好能直接用sql语句不带参数能做到吗?
解决方案 »
- sql server性能问题
- 连接数据库失败
- T-SQL 的函数与存储过程
- 做超大负载量的网站. 优化方面,主要是DB方面,还是程序方面?
- 这条SQL语句还有提升性能的空间吗?
- 如何用sql语句完成得到这个结果,类似于树
- 邹建,误删除了数据,如何还原!急
- 请高手列出ms sqlserver2000所有数据库命令
- 装什么版本的sql server 2005 来解决我的问题
- 一个没有办法的问题???希望能进来帮帮忙???谢谢各位
- 100分求助:帮看下这道题目怎么做!(笔试的时候碰到的,大体意思就是这样的.)
- 请教SQL Server 2000 导出表(字段)到成EXCEL文件 SQL语句 如何编写?
insert tb
select 001, 'AA' union all
select 001, 'BB' union all
select 001, 'CC' union all
select 002, 'DD' union all
select 002, 'EE' union all
select 003, 'FF'
go
CREATE FUNCTION dbo.f_tb(@id int)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @str varchar(8000)
SET @str = ''
SELECT @str = @str + ' ' + CardName FROM tb WHERE CardNo=@id
RETURN STUFF(@str, 1, 1, '')
END
GO SELECT CardNo, CardName = dbo.f_tb(CardNo) FROM tb GROUP BY CardNo
drop table tb
drop function dbo.f_tb
go
--*******************************************************************************************
表结构,数据如下:
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
-- -----------t_mac 小编-------------
---希望有天成为大虾----
-- =========================================IF OBJECT_ID('tb') IS NOT NULL
DROP TABLE tb
GO
CREATE TABLE tb(id int ,name varchar(10))
go
insert tb SELECT
1 , 'as' UNION ALL SELECT
1 , 'sa' UNION ALL SELECT
2 , 'jskh' UNION ALL SELECT
2 , 'asd'UNION ALL SELECT
2 , 'asdasd' UNION ALL SELECT
3 , 'asd'
go
CREATE FUNCTION dbo.f_tb(@id int)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @str varchar(8000)
SET @str = ''
SELECT @str = @str + ',' + Name FROM tb WHERE id=@id
RETURN STUFF(@str, 1, 1, '')
END
GO SELECT id, CardName = dbo.f_tb(id) FROM tb GROUP BY id
drop table tb
drop function dbo.f_tb
go
go
/*------------
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 as,sa
2 jskh,asd,asdasd
3 asd(3 行受影响)
-------*/
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3--合并处理
--定义结果集表变量
DECLARE @t TABLE(col1 varchar(10),col2 varchar(100))--定义游标并进行合并处理
DECLARE tb CURSOR LOCAL
FOR
SELECT col1,col2 FROM tb ORDER BY col1,col2
DECLARE @col1_old varchar(10),@col1 varchar(10),@col2 int,@s varchar(100)
OPEN tb
FETCH tb INTO @col1,@col2
SELECT @col1_old=@col1,@s=''
WHILE @@FETCH_STATUS=0
BEGIN
IF @col1=@col1_old
SELECT @s=@s+','+CAST(@col2 as varchar)
ELSE
BEGIN
INSERT @t VALUES(@col1_old,STUFF(@s,1,1,''))
SELECT @s=','+CAST(@col2 as varchar),@col1_old=@col1
END
FETCH tb INTO @col1,@col2
END
INSERT @t VALUES(@col1_old,STUFF(@s,1,1,''))
CLOSE tb
DEALLOCATE tb
--显示结果并删除测试数据
SELECT * FROM @t
DROP TABLE tb
/*--结果
col1 col2
---------- -----------
a 1,2
b 1,2,3
--*/
GO
/*==============================================*/
--3.3.2 使用用户定义函数,配合SELECT处理完成字符串合并处理的示例
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3
GO--合并处理函数
CREATE FUNCTION dbo.f_str(@col1 varchar(10))
RETURNS varchar(100)
AS
BEGIN
DECLARE @re varchar(100)
SET @re=''
SELECT @re=@re+','+CAST(col2 as varchar)
FROM tb
WHERE col1=@col1
RETURN(STUFF(@re,1,1,''))
END
GO--调用函数
SELECT col1,col2=dbo.f_str(col1) FROM tb GROUP BY col1
--删除测试
DROP TABLE tb
DROP FUNCTION f_str
/*--结果
col1 col2
---------- -----------
a 1,2
b 1,2,3
--*/
GO/*==============================================*/
--3.3.3 使用临时表实现字符串合并处理的示例
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3--合并处理
SELECT col1,col2=CAST(col2 as varchar(100))
INTO #t FROM tb
ORDER BY col1,col2
DECLARE @col1 varchar(10),@col2 varchar(100)
UPDATE #t SET
@col2=CASE WHEN @col1=col1 THEN @col2+','+col2 ELSE col2 END,
@col1=col1,
col2=@col2
SELECT * FROM #t
/*--更新处理后的临时表
col1 col2
---------- -------------
a 1
a 1,2
b 1
b 1,2
b 1,2,3
--*/
--得到最终结果
SELECT col1,col2=MAX(col2) FROM #t GROUP BY col1
/*--结果
col1 col2
---------- -----------
a 1,2
b 1,2,3
--*/
--删除测试
DROP TABLE tb,#t
GO
/*==============================================*/--3.3.4.1 每组 <=2 条记录的合并
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'c',3--合并处理
SELECT col1,
col2=CAST(MIN(col2) as varchar)
+CASE
WHEN COUNT(*)=1 THEN ''
ELSE ','+CAST(MAX(col2) as varchar)
END
FROM tb
GROUP BY col1
DROP TABLE tb
/*--结果
col1 col2
---------- ----------
a 1,2
b 1,2
c 3
--*/--3.3.4.2 每组 <=3 条记录的合并
--处理的数据
CREATE TABLE tb(col1 varchar(10),col2 int)
INSERT tb SELECT 'a',1
UNION ALL SELECT 'a',2
UNION ALL SELECT 'b',1
UNION ALL SELECT 'b',2
UNION ALL SELECT 'b',3
UNION ALL SELECT 'c',3--合并处理
SELECT col1,
col2=CAST(MIN(col2) as varchar)
+CASE
WHEN COUNT(*)=3 THEN ','
+CAST((SELECT col2 FROM tb WHERE col1=a.col1 AND col2 NOT IN(MAX(a.col2),MIN(a.col2))) as varchar)
ELSE ''
END
+CASE
WHEN COUNT(*)>=2 THEN ','+CAST(MAX(col2) as varchar)
ELSE ''
END
FROM tb a
GROUP BY col1
DROP TABLE tb
/*--结果
col1 col2
---------- ------------
a 1,2
b 1,2,3
c 3
--*/
GO
-- -----------t_mac 小编-------------
---希望有天成为大虾----
-- =========================================IF OBJECT_ID('tb') IS NOT NULL
DROP TABLE tb
GO
CREATE TABLE tb(id int ,name varchar(10))
go
insert tb SELECT
1 , 'as' UNION ALL SELECT
1 , 'sa' UNION ALL SELECT
2 , 'jskh' UNION ALL SELECT
2 , 'asd'UNION ALL SELECT
2 , 'asdasd' UNION ALL SELECT
3 , 'asd'
go
select id, name=stuff((select ','+name from tb t where id=tb.id for xml path('')), 1, 1, '')
from tb
group by id go
/*------------
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 as,sa
2 jskh,asd,asdasd
3 asd(3 行受影响)
-------*/
create table hero_girl( id int, name varchar(50))
insert into hero_girl
select 1 , 'as ' union all
select 1 , 'sa' union all
select 2 , 'jskh' union all
select 2 , 'asd' union all
select 2 , 'asdasd' union all
select 3 , 'asd' create function f_hero_girl( @id int)
returns varchar(1000)
as
begin declare @sql varchar(100)
set @sql = ''
select @sql =@sql+[name]+',' from hero_girl where id =@id
return (substring(@sql,1,len(@sql)-1))end
select distinct id,dbo.f_hero_girl(id) from hero_girl
-- Author :fredrickhu(小F 向高手学习)
-- Date :2009-07-22 15:18:35
----------------------------------------------------------------
--> 测试数据:[tb]
if object_id('[tb]') is not null drop table [tb]
create table [tb]([id] int,[name] varchar(6))
insert [tb]
select 1,'as' union all
select 1,'sa' union all
select 2,'jskh' union all
select 2,'asd' union all
select 2,'asdasd' union all
select 3,'asd'
--------------开始查询--------------------------
SELECT * FROM(SELECT DISTINCT id FROM tb)A OUTER APPLY(
SELECT [name]= STUFF(REPLACE(REPLACE(
(
SELECT name FROM tb N
WHERE id = A.id
FOR XML AUTO
), '<N name="', ','), '"/>', ''), 1, 1, '')
)N ----------------结果----------------------------
/*id name
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 as,sa
2 jskh,asd,asdasd
3 asd(3 行受影响)
*/
from tb
group by id
select distinct id,stuff((select ','+[name] from hero_girl where id=A.id for xml path('')),1,1,'') from hero_girl A
id name
1 as
1 sa
1 sa
2 jskh
2 asd
2 asd
2 asdasd
3 asd
得到如下结果:
1 as,sa
2 jskh,asd,asdasd
3 asd 此时怎么做啊
CREATE TABLE tb(ID int,col varchar(50))
INSERT tb SELECT 1,'1,2,3,4'
UNION ALL SELECT 1,'1,3,4'
UNION ALL SELECT 1,'1,4'
UNION ALL SELECT 2,'11,3,4'
UNION ALL SELECT 2,'1,33,4'
UNION ALL SELECT 3,'1,3,4'
GO--1. 字符串并集处理函数
CREATE FUNCTION dbo.f_mergSTR(@ID int)
RETURNS varchar(50)
AS
BEGIN
DECLARE @t TABLE(ID int identity,b bit)
--分拆处理辅助表,由于列col的最大宽度为50,所以只需要1到50的分拆辅助记录
INSERT @t(b) SELECT TOP 50 0
FROM syscolumns DECLARE @r varchar(50)
SET @r=''
SELECT @r=@r+','+s
FROM(
SELECT s=SUBSTRING(a.col,b.ID,CHARINDEX(',',a.col+',',b.ID)-b.ID)
FROM tb a,@t b
WHERE a.ID=@ID
AND b.ID<=LEN(a.col)
AND SUBSTRING(','+a.col,b.ID,1)=','
GROUP BY SUBSTRING(a.col,b.ID,CHARINDEX(',',a.col+',',b.ID)-b.ID)
)a ORDER BY s
RETURN(STUFF(@r,1,1,''))
END
GO--调用用户定义实现交并集查询
SELECT ID,col=dbo.f_mergSTR(ID)
FROM tb
GROUP BY ID
GOID col
----------- --------------------------------------------------
1 1,2,3,4
2 1,11,3,33,4
3 1,3,4
DROP TABLE tb
GO
CREATE TABLE tb(id int ,name varchar(10))
go
insert tb SELECT
1 , 'as' UNION ALL SELECT
1 , 'sa' UNION ALL SELECT
1 , 'sa' UNION ALL SELECT
2 , 'jskh' UNION ALL SELECT
2 , 'asd'UNION ALL SELECT
2 , 'asd'UNION ALL SELECT
2 , 'asdasd' UNION ALL SELECT
3 , 'asd'
go
create FUNCTION dbo.f_mergSTR(@ID int)
RETURNS varchar(50)
AS
BEGIN
DECLARE @t TABLE(ID int identity,b bit)
--分拆处理辅助表,由于列col的最大宽度为50,所以只需要1到50的分拆辅助记录
INSERT @t(b) SELECT TOP 50 0
FROM syscolumns DECLARE @r varchar(50)
SET @r=''
SELECT @r=@r+','+s
FROM(
SELECT s=SUBSTRING(a.name ,b.ID,CHARINDEX(',',a.name +',',b.ID)-b.ID)
FROM tb a,@t b
WHERE a.ID=@ID
AND b.ID<=LEN(a.name )
AND SUBSTRING(','+a.name ,b.ID,1)=','
GROUP BY SUBSTRING(a.name ,b.ID,CHARINDEX(',',a.name +',',b.ID)-b.ID)
)a ORDER BY s
RETURN(STUFF(@r,1,1,''))
END
GO--调用用户定义实现交并集查询
SELECT ID,name =dbo.f_mergSTR(ID)
FROM tb
GROUP BY ID
goID name
----------- --------------------------------------------------
1 as,sa
2 asd,asdasd,jskh
3 asd
-- -----------t_mac 小编-------------
---希望有天成为大虾----
-- =========================================IF OBJECT_ID('tb') IS NOT NULL
DROP TABLE tb
GO
CREATE TABLE tb(id int ,name varchar(10))
go
insert tb SELECT
1 , 'as' UNION ALL SELECT
1 , 'sa' UNION ALL SELECT
1 , 'sa' UNION ALL SELECT
2 , 'jskh' UNION ALL SELECT
2 , 'asd'UNION ALL SELECT
2 , 'asd'UNION ALL SELECT
2 , 'asdasd' UNION ALL SELECT
3 , 'asd'
goselect id, name=stuff((select ','+name from (select distinct * from tb) t where id=tb.id for xml path('')), 1, 1, '')
from tb
group by id
(8 行受影响)
id name
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 as,sa
2 asd,asdasd,jskh
3 asd
insert tb
select 1, 'as' union all
select 1, 'sa' union all
select 1, 'sa' union all
select 2, 'jskh' union all
select 2, 'asd' union all
select 2, 'asd' union all
select 2, 'asdasd' union all
select 3, 'asd'
select CardNo,name=stuff((select distinct ','+cardname from tb where CardNo=t.CardNo for xml path('')),1,1,'')
from tb t group by CardNo/*
CardNo name
----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 as,sa
2 asd,asdasd,jskh
3 asd(3 行受影响)*/
--如果是2000 就得用函数了 没其他办法
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 t.id = tb.id
for xml path('')), 1, 1, '')
from tb
group by id这个方法很好,学习了...