2011-04-08 119 views
0

我需要一个像一行T-SQL汇总数

CREATE TABLE #t(num int); 

INSERT #t 
SELECT 10001 UNION ALL 
SELECT 10002 UNION ALL 
SELECT 10003 UNION ALL 
SELECT 10004 UNION ALL 
SELECT 10005 UNION ALL 
SELECT 10006 UNION ALL 
SELECT 10007 UNION ALL 
SELECT 10008 UNION ALL 
SELECT 10009 UNION ALL 
SELECT 10010 UNION ALL 
SELECT 10020 UNION ALL 
SELECT 10030 UNION ALL 
SELECT 10040 UNION ALL 
SELECT 10041 UNION ALL 
SELECT 10042 UNION ALL 
SELECT 10043 UNION ALL 
SELECT 10050 UNION ALL 
SELECT 10060 UNION ALL 
SELECT 10070 UNION ALL 
SELECT 10075 UNION ALL 
SELECT 10076 UNION ALL 
SELECT 10077; 

--DROP TABLE #T; 

总结编号,以简单的形式在该结果是这样的方式。

10001-10010, 10020, 10030, 10040-10043, 10050, 10060, 10070, 10075-10077 

任何帮助将不胜感激。

+0

有可能是一个聪明的办法用TSQL的程序做,但它可能更容易只是把一个查询一起在你的应用程序的语言。那会是什么语言? – 2011-04-08 18:52:24

+0

什么版本的sql server? – 2011-04-08 18:55:44

+1

你是对的,但我们正在CSharp.net中重新设计遗留应用程序(vb6)。 :) – 2011-04-08 18:56:11

回答

5

试试这个:

WITH CTE1 AS 
(
    SELECT *, num - ROW_NUMBER() OVER(ORDER BY num) Corr 
    FROM #t 
), CTE2 AS 
(
    SELECT MIN(num) MinNum, MAX(num) MaxNum, Corr 
    FROM CTE1 
    GROUP BY Corr 
) 

SELECT CAST(MinNum AS VARCHAR) + 
     CASE WHEN MaxNum != MinNum THEN ' - ' + CAST(MaxNum AS VARCHAR) ELSE '' END Res 
FROM CTE2 
4
DECLARE @Result VARCHAR(MAX); 

WITH q AS (
SELECT 
    Num, 
    Num - (ROW_NUMBER() OVER (ORDER BY Num)) AS RowNumber 
FROM 
    #t 
) 
SELECT 
    @Result = ISNULL(@Result + ',', '') + 
    CASE WHEN MIN(Num) != MAX(Num) 
     THEN CAST(MIN(Num) AS VARCHAR) + '-' + CAST(MAX(Num) AS VARCHAR) 
     ELSE CAST(MIN(Num) AS VARCHAR) 
    END 
FROM q 
GROUP BY RowNumber 

PRINT @Result 
-- Or... SELECT @Result.. whichever. 
+0

非常感谢。 – 2011-04-08 19:23:24

1

尝试光标。 运行脚本来创建表,那么这个

DECLARE cur CURSOR FOR 
SELECT num FROM #t 

OPEN cur 
DECLARE @nm INT; 
DECLARE @start INT; 
DECLARE @prev INT; 
DECLARE @retVal VARCHAR(MAX); 
SET @retVal = ''; 

FETCH NEXT FROM cur INTO @nm 
SET @prev = NULL; 
SET @start = NULL; 
WHILE (@@fetch_status = 0) 
BEGIN 
    IF (@prev IS NOT NULL) 
    BEGIN 
     IF (@prev = @nm - 1) 
     BEGIN 
      SET @prev = @nm; 
     END 
     ELSE 
     BEGIN 
      IF (@start = @prev) 
       SET @retVal = @retVal + CAST(@start AS VARCHAR) + ', ' 
      ELSE 
       SET @retVal = @retVal + CAST(@start AS VARCHAR) + ' - ' + CAST(@prev AS VARCHAR) + ', ' 

      SET @prev = @nm; 
      SET @start = @nm; 
     END 
    END 
    ELSE 
    BEGIN 
     SET @prev = @nm; 
     SET @start = @nm; 
    END 

    --PRINT(@nm) 
    FETCH NEXT FROM cur INTO @nm 
END 

CLOSE cur 
DEALLOCATE cur 

IF (@start = @prev) 
    SET @retVal = @retVal + CAST(@start AS VARCHAR) + ', ' 
ELSE 
    SET @retVal = @retVal + CAST(@start AS VARCHAR) + ' - ' + CAST(@prev AS VARCHAR) + ', ' 

IF (LEN(@retVal) > 1) 
    SET @retVal = SUBSTRING(@retVal, 1, LEN(@retVal) - 1) 

PRINT(@retVal) 
+0

nooooooooooo .....不要这样做。永远。 – 2011-04-08 19:08:13

+0

你可能想为你的游标声明添加'FAST_FORWARD' – 2011-04-08 19:20:48

+0

@nathan gonzalez为什么? – 2011-04-08 19:29:00