搜藏 SQL

问题: http://topic.csdn.net/u/20090917/16/DC77BFD0-78E9-4837-9B46-388446691676.html
表 a:
编号    值
000055 2
000057 2
000059 2
000060 2
000061 2
000062 2
000063 2
000064 2
000065 3
000066 1
000600 1

要求得到如下结果:
编号                          值
000055,000057,000059-000064  2
000065                        3
000066,000600                1
将值相同的记录合并成一行,同时将连续的编号写成“起始编号-结束编号”的形式。
解决:
方案一:

IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
CREATE TABLE [tb] (编号 varchar(6),值 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

--SQL查询如下:

GO
CREATE FUNCTION dbo.MergeNo(@值 int)
    RETURNS varchar(8000)
AS
BEGIN
    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,'');
END
GO

SELECT 值 ,dbo.MergeNo(值) AS 编号
FROM tb
GROUP BY 值
GO
DROP TABLE tb
DROP FUNCTION dbo.MergeNo

/*
值    编号
1    000066,000600
2    000055,000057,000059~000064
3    000065
*/
=======================================
SQL2000 方案二:
IF NOT OBJECT_ID('[tb]') IS NULL
   
DROP TABLE [tb]
GO
CREATE TABLE [tb]([编号] NVARCHAR(10),[] INT)
INSERT [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
GO
--SELECT * FROM [tb]

-->SQL查询如下:
IF NOT OBJECT_ID('[fn_str]') IS NULL
   
DROP FUNCTION fn_str
GO
CREATE FUNCTION fn_str(@i INT)
RETURNS VARCHAR(100)
AS
BEGIN
   
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 @s
END
GO

SELECT DISTINCT dbo.FN_STR(值) AS [编号],值 FROM tb

================================================
SQL2005 -2008
   IF NOT OBJECT_ID('[tb]') IS NULL
   
DROP TABLE [tb]
GO
CREATE TABLE [tb]([编号] NVARCHAR(10),[] INT)
INSERT [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
GO
--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    2
000065    3
000066,000600    1
*/

原文地址:https://www.cnblogs.com/ggbbeyou/p/1572351.html