T-SQL汇总一行中的数字

时间:2011-04-08 18:49:01

标签: tsql sql-server-2008

我需要总结一下像

这样的数字
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

任何帮助都将受到高度赞赏。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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.

答案 2 :(得分: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)