多条记录合并为一条,同时将连续的编号写成“起始编号-结束编号”的形式
表 a:
编号 值
0000552
0000572
0000592
0000602
0000612
0000622
0000632
0000642
0000653
0000661
0006001
要求得到如下结果:
编号 值
000055,000057,000059-000064 2
000065 3
000066,000600 1
将值相同的记录合并成一行,同时将连续的编号写成“起始编号-结束编号”的形式。
[解决办法]
- SQL code
--------------------------------------- Author : liangCK 梁爱兰-- Comment: 小梁 爱 兰儿-- Date : 2009-09-17 16:53:30------------------------------------- --> 生成测试数据: @tbDECLARE @tb TABLE (编号 varchar(6),值 int)INSERT INTO @tbSELECT '000055',2 UNION ALLSELECT '000057',2 UNION ALLSELECT '000059',2 UNION ALLSELECT '000060',2 UNION ALLSELECT '000061',2 UNION ALLSELECT '000062',2 UNION ALLSELECT '000063',2 UNION ALLSELECT '000064',2 UNION ALLSELECT '000065',3 UNION ALLSELECT '000066',1 UNION ALLSELECT '000600',1--SQL查询如下:;WITH Liang AS( SELECT ROW_NUMBER() OVER(PARTITION BY 值 ORDER BY 值) - 编号 AS rowid,* FROM @tb),Liang2 AS( SELECT 值,rowid,CASE WHEN COUNT(*) > 1 THEN RTRIM(MIN(编号))+'~'+RTRIM(MAX(编号)) ELSE RTRIM(MIN(编号)) END AS flag FROM Liang GROUP BY 值,rowid)SELECT STUFF((SELECT ',' + flag AS [text()] FROM Liang2 WHERE 值 = A.值 FOR XML PATH('')),1,1,'') AS 编号, 值FROM Liang2 AS AGROUP BY 值/*编号 值000600,000066 1000059~000064,000057,000055 2000065 3*/
[解决办法]
- SQL code
/*----------------------------------- Author : htl258(Tony)-- Date : 2009-09-17 16:53:11-- Version: Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) Mar 29 2009 10:27:29 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Evaluation Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 2)---------------------------------*/--> 生成测试数据表:tbIF NOT OBJECT_ID('[tb]') IS NULL DROP TABLE [tb]GOCREATE TABLE [tb]([编号] NVARCHAR(10),[值] INT)INSERT [tb]SELECT '000055',2 UNION ALLSELECT '000057',2 UNION ALLSELECT '000059',2 UNION ALLSELECT '000060',2 UNION ALLSELECT '000061',2 UNION ALLSELECT '000062',2 UNION ALLSELECT '000063',2 UNION ALLSELECT '000064',2 UNION ALLSELECT '000065',3 UNION ALLSELECT '000066',1 UNION ALLSELECT '000600',1GO--SELECT * FROM [tb]-->SQL查询如下:;WITH t AS( SELECT CASE WHEN a.编号=b.编号 THEN a.编号 ELSE a.编号+'-'+b.编号 END AS 编号,a.值 FROM ( SELECT rn=ROW_NUMBER()OVER(ORDER BY GETDATE()),* FROM tb t WHERE NOT EXISTS( SELECT 1 FROM tb WHERE [值]=t.值 AND [编号]=t.[编号]+1) ) AS a JOIN ( SELECT rn=ROW_NUMBER()OVER(ORDER BY GETDATE()),* FROM tb t WHERE NOT EXISTS( SELECT 1 FROM tb WHERE [值]=t.值 AND t.[编号]=[编号]+1) ) AS b ON a.rn=b.rn) SELECT DISTINCT 编号=STUFF((SELECT ','+编号 FROM t WHERE 值=a.值 FOR XML PATH('')),1,1,''),值FROM t a/*编号 值000055,000057,000064-000059 2000065 3000066,000600 1*/
[解决办法]
- SQL code
sql2000:CREATE TABLE tgss(a VARCHAR(20),b INT)INSERT tgss SELECT '000055',2 union all select '000057', 2 union all select '000059', 2 union all select '000060', 2 union all select '000061', 2 union all select '000062', 2 union all select '000063', 2 union all select '000064', 2 union all select '000065', 3 union all select '000066', 1 union all select '000600', 1ALTER TABLE tgss ADD g INTDECLARE @i INT,@l VARCHAR(20),@sql VARCHAR(2000) SET @i=0UPDATE tgss SET @i=CASE WHEN a*1=@l*1+1 THEN @i ELSE @i+1 end,@l=a,g=@igoSELECT b,g,CASE WHEN MIN(a)=MAX(a) THEN MIN(a) ELSE MIN(a)+'-'+MAX(a) END e into tgssA FROM tgss GROUP BY b,ggoCREATE FUNCTION ltgss(@b INT )RETURNS VARCHAR(1000)AS BEGIN declare @sql VARCHAR(1000) SELECT @sql=ISNULL(@sql+',','')+e FROM tgssA WHERE b=@b ORDER BY g RETURN @sqlENDgoSELECT b,dbo.ltgss(b) ee FROM tgssA GROUP BY b--result/*b ee ----------- ------------------------------ 1 000066,0006002 000055,000057,000059-0000643 000065(所影响的行数为 3 行)*/
[解决办法]
用临时表(函数里不能用临时表,所以用了一个t3)写个2000的试试
- SQL code
if object_id('[a]') is not null drop table [a]gocreate table [a]([编号] varchar(6),[值] int)insert [a]select '000055',2 union allselect '000057',2 union allselect '000059',2 union allselect '000060',2 union allselect '000061',2 union allselect '000062',2 union allselect '000063',2 union allselect '000064',2 union allselect '000065',3 union allselect '000066',1 union allselect '000600',1select *,tid=identity(int,1,1) into #1 from a t where not exists(select 1 from a where 值=t.值 and 编号=t.编号-1)select *,tid=identity(int,1,1) into #2 from a t where not exists(select 1 from a where 值=t.值 and 编号=t.编号+1)select a.编号 as no1,b.编号 as no2,a.值 as val into t3 from #1 a,#2 b where a.tid=b.tidcreate function f_str(@val int)returns varchar(30)asbegin declare @s varchar(30) select @s=isnull(@s+',','') +case when no1=no2 then no1 else no1+'~'+no2 end from t3 where val=@val order by no1 return @sendselect distinct dbo.f_str(val) as 编号,val as 值 from t3drop table #1,#2,t3drop function f_str--测试结果:/*编号 值------------------------------ -----------000055,000057,000059~000064 2000065 3000066,000600 1(3 行受影响)*/
[解决办法]
- SQL code
--------------------------------------- Author : liangCK 梁爱兰-- Comment: 小梁 爱 兰儿-- Date : 2009-09-17 17:09:41------------------------------------- --> 生成测试数据: [tb]IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]CREATE TABLE [tb] (编号 varchar(6),值 int)INSERT INTO [tb]SELECT '000055',2 UNION ALLSELECT '000057',2 UNION ALLSELECT '000059',2 UNION ALLSELECT '000060',2 UNION ALLSELECT '000061',2 UNION ALLSELECT '000062',2 UNION ALLSELECT '000063',2 UNION ALLSELECT '000064',2 UNION ALLSELECT '000065',3 UNION ALLSELECT '000066',1 UNION ALLSELECT '000600',1--SQL查询如下:GOCREATE FUNCTION dbo.MergeNo(@值 int) RETURNS varchar(8000)ASBEGIN DECLARE @re varchar(8000); SET @re = ''; SELECT @re = @re + CASE WHEN EXISTS(SELECT * FROM tb WHERE 值 = A.值 AND CAST(编号 AS int) -1 = CAST(A.编号 AS int)) THEN CASE WHEN RIGHT(@re,1) <> '~' THEN ',' + 编号 + '~' ELSE '' END ELSE CASE WHEN EXISTS(SELECT * FROM tb WHERE 值 = A.值 AND CAST(编号 AS int) + 1 = CAST(A.编号 AS int)) THEN 编号 ELSE ',' + 编号 END END FROM tb AS A WHERE 值 = @值 ORDER BY 编号; RETURN STUFF(@re,1,1,'');ENDGOSELECT 值 ,dbo.MergeNo(值) AS 编号FROM tbGROUP BY 值GODROP TABLE tbDROP FUNCTION dbo.MergeNo/*值 编号1 000066,0006002 000055,000057,000059~0000643 000065*/
[解决办法]
- SQL code
--> 生成测试数据表:tbIF NOT OBJECT_ID('[tb]') IS NULL DROP TABLE [tb]GOCREATE TABLE [tb]([编号] NVARCHAR(10),[值] INT)INSERT [tb]SELECT '000055',2 UNION ALLSELECT '000057',2 UNION ALLSELECT '000059',2 UNION ALLSELECT '000060',2 UNION ALLSELECT '000061',2 UNION ALLSELECT '000062',2 UNION ALLSELECT '000063',2 UNION ALLSELECT '000064',2 UNION ALLSELECT '000065',3 UNION ALLSELECT '000066',1 UNION ALLSELECT '000600',1GO--SELECT * FROM [tb]-->SQL查询如下:IF NOT OBJECT_ID('[fn_str]') IS NULL DROP FUNCTION fn_strGOCREATE FUNCTION fn_str(@i INT)RETURNS VARCHAR(100)ASBEGIN DECLARE @s VARCHAR(100) SELECT @s=ISNULL(@s+',','')+CASE WHEN MIN(a.编号)=b.编号 THEN b.编号 ELSE b.编号+'-'+MIN(a.编号) END FROM ( SELECT * FROM tb t WHERE NOT EXISTS( SELECT 1 FROM tb WHERE [值]=t.值 AND [编号]=t.[编号]+1) ) AS a JOIN ( SELECT * FROM tb t WHERE NOT EXISTS( SELECT 1 FROM tb WHERE [值]=t.值 AND t.[编号]=[编号]+1) ) AS b ON a.值=b.值 AND a.编号>=b.编号 GROUP BY a.值,b.编号 HAVING a.值=@i RETURN @sENDGOSELECT DISTINCT dbo.FN_STR(值) AS [编号],值 FROM tb/*编号 值---------------------------------------------------------------- -----------000055,000057,000059-000064 2000065 3000066,000600 1(3 行受影响)*/
[解决办法]
谨以此SQL代码表达我对梁哥的崇敬之情,梁哥你是我的偶像
- SQL code
IF OBJECT_ID('TEMP') IS NOT NULL DROP TABLE TEMP
IF OBJECT_ID('FUN_TEST') IS NOT NULL DROP FUNCTION FUN_TEST
IF OBJECT_ID('FUN_TEST2') IS NOT NULL DROP FUNCTION FUN_TEST2
GO
CREATE FUNCTION FUN_TEST(@VAL INT,@VAL2 INT)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @STR VARCHAR(8000)
IF @VAL2 <>1
SELECT @STR=ISNULL(@STR+',','')+ID FROM TEMP WHERE VAL=@VAL AND VAL2=@VAL2
ELSE
BEGIN
SELECT @STR=ID2 FROM TEMP T1 WHERE NOT EXISTS(SELECT 1 FROM TEMP T2 WHERE T2.VAL=T1.VAL AND
T2.VAL2=T1.VAL2 AND T2.ID2 <T1.ID2) AND T1.VAL=@VAL AND T1.VAL2=@VAL2
SELECT @STR=@STR+'-'+ID FROM TEMP T1 WHERE NOT EXISTS(SELECT 1 FROM TEMP T2 WHERE T2.VAL=T1.VAL AND
T2.VAL2=T1.VAL2 AND T2.ID2>T1.ID2) AND T1.VAL=@VAL AND T1.VAL2=@VAL2
END
RETURN @STR
END
GO
CREATE FUNCTION FUN_TEST2(@VAL INT)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @STR VARCHAR(8000)
SELECT @STR=ISNULL(@STR+',','')+VAL3
FROM (
SELECT VAL,VAL2
,DBO.FUN_TEST(VAL,VAL2) 'VAL3'
FROM TEMP WHERE VAL=@VAL
GROUP BY VAL,VAL2
) T
RETURN @STR
END
GO
DECLARE @tb TABLE (ID varchar(6),VAL int)
INSERT INTO @tb
SELECT '000055',2 UNION ALL
SELECT '000057',2 UNION ALL
SELECT '000059',2 UNION ALL
SELECT '000060',2 UNION ALL
SELECT '000061',2 UNION ALL
SELECT '000062',2 UNION ALL
SELECT '000063',2 UNION ALL
SELECT '000064',2 UNION ALL
SELECT '000065',3 UNION ALL
SELECT '000066',1 UNION ALL
SELECT '000600',1
CREATE TABLE TEMP(
ID VARCHAR(10),
VAL INT,
ID2 VARCHAR(10),
VAL2 INT
)
INSERT INTO TEMP
SELECT ID,VAL
,ISNULL((SELECT MAX(ID) FROM @TB T2 WHERE T2.VAL=T1.VAL AND T2.ID <T1.ID),ID) 'ID2'
,ISNULL(CAST(ID AS INT)-(SELECT cast(MAX(ID) AS INT) FROM @TB T2 WHERE T2.VAL=T1.VAL AND T2.ID <T1.ID),0) 'VAL2'
FROM @TB T1
SELECT VAL
,DBO.FUN_TEST2(VAL) 'STR'
FROM TEMP
GROUP BY VAL
/*
1000066,000600
2000055,000059-000064,000057,000059
3000065
*/
[解决办法]
- SQL code
if object_id('[tb]') is not null drop table [tb]go create table [tb]([编号] varchar(6),[值] int)insert [tb]select '000055',2 union allselect '000057',2 union allselect '000059',2 union allselect '000060',2 union allselect '000061',2 union allselect '000062',2 union allselect '000063',2 union allselect '000064',2 union allselect '000065',3 union allselect '000066',1 union allselect '000600',1create table tt(编号 varchar(20),值 int )select *,id=identity(int,1,1) into #t from tb insert tt select 编号,值 from #t twhere exists(select * from #t where id=t.id+1 and 值=t.值 and cast(编号 as int)=cast(t.编号 as int)+1)insert tt select right('00000'+ltrim(cast(max(编号) as int)+1),6),值 from tt group by 值if object_id('f_str')is not null drop function f_strgocreate function f_str(@zhi int)returns varchar(100)asbegin declare @s varchar(100) select @s=isnull(@s+',','')+编号 from tb where 值=@zhi and 编号 not in (select 编号 from tt) if (select count(*) from tt where 值=@zhi)>0 set @s=@s+','+(select min(编号)from tt)+'-'+(select max(编号)from tt) return @sendgoselect 值,编号=dbo.f_str(值) from tbgroup by 值值 编号----------- ----------------------------------------------------------------1 000066,0006002 000055,000057,000059-0000643 000065(3 行受影响)drop table ttdrop table #t
[解决办法]
这个也不一定是.net,如果数据量太大,从数据库读太多数据确实不划算。我也不知道怎么写,建议楼主可以考虑下用存储过程,会比较快一些。我们公司在做项目时,遇到像你这种问题老大也都是要求放数据库里面操作的,放应用程序处理的话单单传数据就要浪费大量的时间了。考虑业务分层是没错,可是更要考虑数据量,否则分层就成了累赘。
[解决办法]
[解决办法]
- SQL code
--1.建表create table tmptb(num varchar(12)not null primary key,groupid int )--2.向表中插入数据insert into tmptbselect 'abcdefg',1union allselect 'hijklmno',1union allselect 'lmnopqrst',1union allselect 'afasfdas',2union allselect 'rgfdgafaw',2union allselect 'dfewtqwr',3union allselect 'cvczxa',4union allselect 'cftreyas',4--3.建一个函数alter function myFunc( @groupid int )returns varchar(100)asbegindeclare @retnum varchar(100)set @retnum=''select @retnum=@retnum+','+num from tmptb where groupid=@groupidset @retnum=substring(ltrim(@retnum),2,len(@retnum)-2)return @retnumend--4.执行查询select distinct groupid,dbo.myfunc(groupid) from tmptb
[解决办法]
[解决办法]