搜藏 SQL
表 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
*/