TAB1:
arcID arcAuthor ...
1 user1
2 user2
3 user3
4 user2
Tab2:
id arcID piShi
1 1 公司采用
2 1 公司领导批示
3 1 集团采用
4 1 集团领导批示
5 2 公司采用
6 2 公司领导批示
7 2 集团采用
8 3 公司采用现在需要根据采用情况和批示情况进行汇总,汇总后报表如下:
arcID arcAuthor caiYong Pishi
1 user1 公司采用/集团采用 公司领导批示/集团领导批示
2 user2 公司采用/集团采用 公司领导批示
3 user3 公司采用
4 user2
如何用SQL汇总?
解决方案 »
- SQL 2008里varchar(max)字段的问题。
- 无法绑定由多个部分组成的标识符 "SystemOperators.OperatorId"。
- sql查询问题急!
- 对我来说有难度的SQL
- 数据导入问题
- 哪位高手师傅帮我用SQL语句把下面的报表写出来,谢谢了!急用!
- 两个表的比较,怎么写sql语句
- sql server的乱码问题,可以正常显示,但是察看数据库只能看到乱码。why
- 求助高手!Virual C++调用ADO访问MS SQL Server出现内存泄漏问题,
- 关于同数据库多表操作问题,望各位大神解答,谢谢!
- SQL里有没有gb2312转换成UTF-8的方法
- 如何用语句实现请指教,在线等,谢谢
无论是在sql 2000,还是在 sql 2005 中,都没有提供字符串的聚合函数,
所以,当我们在处理下列要求时,会比较麻烦:
有表tb, 如下:
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. 旧的解决方法-- 1. 创建处理函数
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, values=dbo.f_str(id)
FROM tb
GROUP BY id-- 2. 新的解决方法
-- 示例数据
DECLARE @t TABLE(id int, value varchar(10))
INSERT @t SELECT 1, 'aa'
UNION ALL SELECT 1, 'bb'
UNION ALL SELECT 2, 'aaa'
UNION ALL SELECT 2, 'bbb'
UNION ALL SELECT 2, 'ccc'-- 查询处理
SELECT *
FROM(
SELECT DISTINCT
id
FROM @t
)A
OUTER APPLY(
SELECT
[values]= STUFF(REPLACE(REPLACE(
(
SELECT value FROM @t N
WHERE id = A.id
FOR XML AUTO
), '<N value="', ','), '"/>', ''), 1, 1, '')
)N/*--结果
id values
----------- ----------------
1 aa,bb
2 aaa,bbb,ccc
(2 行受影响)
--*/--各种字符串分函数--3.3.1 使用游标法进行字符串合并处理的示例。
--处理的数据
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
if not object_id('A') is null
drop table A
Go
Create table A([id] int,[cname] nvarchar(2))
Insert A
select 1,N'张三' union all
select 2,N'李四' union all
select 3,N'王五' union all
select 4,N'蔡六'
Go
--> -->
if not object_id('B') is null
drop table B
Go
Create table B([id] int,[cname] nvarchar(5))
Insert B
select 1,N'1,2,3' union all
select 2,N'3,4'
Go
create function F_str(@cname nvarchar(100))
returns nvarchar(100)
as
begin
select @cname=replace(@cname,ID,[cname]) from A where patindex('%,'+rtrim(ID)+',%',','+@cname+',')>0
return @cname
end
go
select [id],dbo.F_str([cname])[cname] from Bid cname
----------- ----------------------------------------------------------------------------------------------------
1 张三,李四,王五
2 王五,蔡六(2 個資料列受到影響)
go
create table tab1([arcID] int,[arcAuthor] varchar(10))
insert tab1 select 1,'user1'
union all select 2,'user2'
union all select 3,'user3'
union all select 4,'user2'
go
if object_id('tab2') is not null drop table tab2
go
create table tab2([id] int,[arcID] int,[piShi] varchar(20))
insert tab2 select 1,1,'公司采用'
union all select 2,1,'公司领导批示'
union all select 3,1,'集团采用'
union all select 4,1,'集团领导批示'
union all select 5,2,'公司采用'
union all select 6,2,'公司领导批示'
union all select 7,2,'集团采用'
union all select 8,3,'公司采用'
go
if object_id('f_str1') is not null drop function f_str1
go
create function dbo.f_str1(@arcID int) returns varchar(100)
as
begin
declare @str varchar(8000)
select @str = isnull(@str + '/','') + [piShi] from tab2 where arcID = @arcID and charindex('采用',[piShi])>0
return @str
end
go
if object_id('f_str2') is not null drop function f_str2
go
create function dbo.f_str2(@arcID int) returns varchar(100)
as
begin
declare @str varchar(8000)
select @str = isnull(@str + '/','') + [piShi] from tab2 where arcID = @arcID and charindex('批示',[piShi])>0
return @str
end
go
select *,isnull(dbo.f_str1(arcID),'') caiYong,isnull(dbo.f_str2(arcID),'') piShi from tab1
/*
arcID arcAuthor caiYong piShi
----------- ---------- ---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
1 user1 公司采用/集团采用 公司领导批示/集团领导批示
2 user2 公司采用/集团采用 公司领导批示
3 user3 公司采用
4 user2 (4 行受影响)
*/
create table #1(arcID int,arcAuthor varchar(20))
insert #1 values(1, 'user1')
insert #1 values(2, 'user2')
insert #1 values(3, 'user3')
insert #1 values(4, 'user2') create table #2(id int,arcID int,piShi varchar(30))
insert #2 values(1, 1, '公司采用')
insert #2 values(2, 1, '公司领导批示')
insert #2 values(3, 1, '集团采用')
insert #2 values(4, 1, '集团领导批示')
insert #2 values(5, 2, '公司采用')
insert #2 values(6, 2, '公司领导批示')
insert #2 values(7, 2, '集团采用')
insert #2 values(8, 3, '公司采用')select *
,caiYong = stuff((select '/'+piShi from #2 where arcid = a.arcid and pishi like '%采用' for xml path('')),1,1,'')
,Pishi = stuff((select '/'+piShi from #2 where arcid = a.arcid and pishi like '%批示' for xml path('')),1,1,'')
from #1 a
/*
arcID arcAuthor caiYong Pishi
----------- -------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 user1 公司采用/集团采用 公司领导批示/集团领导批示
2 user2 公司采用/集团采用 公司领导批示
3 user3 公司采用 NULL
4 user2 NULL NULL(4 row(s) affected)*/
arcID arcAuthor caiYong Pishi
----------- -------------------- -------------------------------------------------------------------
1 user1 公司采用/集团采用 公司领导批示/集团领导批示
2 user2 公司采用/集团采用 公司领导批示
3 user3 公司采用 NULL
4 user2 NULL NULL(4 row(s) affected)*/
insert into tab1
select '1','user1'
union all select '2','user2'
union all select '3','user3'
union all select '4','user2'create table tab2(id int ,arcID int, piShi varchar(20) )
insert into tab2
select '1','1','公司采用'
union all select '2','1','公司领导批示'
union all select '3','1','集团采用'
union all select '4','1','集团领导批示'
union all select '5','2','公司采用'
union all select '6','2','公司领导批示'
union all select '7','2','集团采用'
union all select '8','3','公司采用'select * from tab1
select * from tab2
create function dbo.fn_a(@id int,@s varchar(20))
returns varchar(1000)
as
begin
declare @a varchar(1000),@b varchar(1000)
declare @i int
set @a=''
select @a=@a+piShi+'/'
from tab2
where arcID=@id and charindex(@s,piShi)>0
if @a<>''
set @a=left(@a,len(@a)-1)
return(@a)
end-- drop function dbo.fn_a
-- drop table tab1,tab2select a.arcID,a.arcAuthor,dbo.fn_a(a.arcID,'采用') as caiYong,dbo.fn_a(a.arcID,'批示') as piShi
from tab1 a
left join tab2 b on a.arcID=b.arcID
group by a.arcID,a.arcAuthorarcID arcAuthor caiYong piShi
--------------------------------------------
1 user1 公司采用/集团采用 公司领导批示/集团领导批示
2 user2 公司采用/集团采用 公司领导批示
3 user3 公司采用
4 user2
(
arcID int,
arcAuthor varchar(20)
)
insert into arc select 1,'user1'
union all select 2,'user2'
union all select 3,'user3'
union all select 4,'user2'
create table ArcpiShi
(
id int,
arcID int,
piShi varchar(30)
)
insert into ArcpiShi select 1,1,'公司采用'
union all select 2,1,'公司领导批示'
union all select 3,1,'集团采用'
union all select 4,1,'集团领导批示'
union all select 5,2,'公司采用'
union all select 6,2,'公司领导批示'
union all select 7,2,'集团采用'
union all select 8,3,'公司采用'CREATE FUNCTION dbo.f_strdadadad(@id int)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @r varchar(8000)
SET @r = ''
SELECT @r = @r + '/' + piShi
FROM XX
WHERE arcID=@id and charindex('采用',piShi)>0
RETURN STUFF(@r, 1, 1, '')
END
GOCREATE FUNCTION dbo.f_strdadadadadadd(@id int)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @r varchar(8000)
SET @r = ''
SELECT @r = @r + '/' + piShi
FROM XX
WHERE arcID=@id and charindex('批示',piShi)>0
RETURN STUFF(@r, 1, 1, '')
END
GO
if object_id('tab1') is not null drop table tab1
go
create table tab1([arcID] int,[arcAuthor] varchar(10))
insert tab1 select 1,'user1'
union all select 2,'user2'
union all select 3,'user3'
union all select 4,'user2'
goif object_id('tab2') is not null drop table tab2
go
create table tab2([id] int,[arcID] int,[piShi] varchar(20))
insert tab2 select 1,1,'公司采用'
union all select 2,1,'公司领导批示'
union all select 3,1,'集团采用'
union all select 4,1,'集团领导批示'
union all select 5,2,'公司采用'
union all select 6,2,'公司领导批示'
union all select 7,2,'集团采用'
union all select 8,3,'公司采用'
goif object_id('dbo.f_getcaiyong') is not null
drop function dbo.f_getcaiyong
go
create function f_getcaiyong(@arcID int)
returns varchar(100)
as
begin
declare @s varchar(100)
set @s=''
select @s =@s+ '/'+piShi from tab2 where arcid=@arcid and charindex('采用',piShi)>0
select @s=stuff(@s,1,1,'')
return @s
end
goif object_id('dbo.f_getpiShi') is not null
drop function dbo.f_getpiShi
go
create function f_getpiShi(@arcID int)
returns varchar(100)
as
begin
declare @s varchar(100)
set @s=''
select @s =@s+ '/'+piShi from tab2 where arcid=@arcid and charindex('批示',piShi)>0
select @s=stuff(@s,1,1,'')
return @s
end
go
select arcid,arcauthor,isnull(dbo.f_getcaiyong(arcid),'') as CaiYong,isnull(dbo.f_getpiShi(arcid),'') as PiShi
from
(select a.arcid,a.arcauthor,b.piShi from tab1 a left join tab2 b on a.arcID = b.arcID)t
group by arcid,arcauthor
go
drop function dbo.f_getcaiyong,dbo.f_getpiShi
drop table tab1,tab2