替换字符串中的连续数字

Kas*_*shi 2 sql-server sql-server-2012

因此,如果我有一个带有值的表:

Name   ID        
----   ---
James  100
James  101 
James  102
James  200
James  201 
James  202 
Alex   100
Alex   101 
Alex   102
Alex   105 
Alex   106
Alex   109 
Alex   109
Alex   500
Alex   501 
Alex   102
Run Code Online (Sandbox Code Playgroud)

我希望结果看起来像这样

Name   ID        
----   ---
James  100-102, 201-202
Alex   100-102, 105-106, 109, 500-502
Run Code Online (Sandbox Code Playgroud)

我知道,我可以使用 FOR XML PATH('') 连续转换数据。但我不确定如何用 - 替换连续数字。任何指导我走向正确方向的帮助将不胜感激。谢谢。

Han*_*non 5

我使用了以下内容,它可以让您部分了解那里。

USE tempdb;
GO
CREATE TABLE Test
(
    uname VARCHAR(255)
    , num INT
);

INSERT INTO Test (uname, num) VALUES ('Max', 1);
INSERT INTO Test (uname, num) VALUES ('Max', 2);
INSERT INTO Test (uname, num) VALUES ('Max', 3);
INSERT INTO Test (uname, num) VALUES ('Max', 4);
INSERT INTO Test (uname, num) VALUES ('Max', 5);
INSERT INTO Test (uname, num) VALUES ('Max', 11);
INSERT INTO Test (uname, num) VALUES ('Max', 12);
INSERT INTO Test (uname, num) VALUES ('Max', 13);
INSERT INTO Test (uname, num) VALUES ('Max', 14);
INSERT INTO Test (uname, num) VALUES ('Max', 15);

INSERT INTO Test (uname, num) VALUES ('Jen', 22);
INSERT INTO Test (uname, num) VALUES ('Jen', 23);
INSERT INTO Test (uname, num) VALUES ('Jen', 24);
INSERT INTO Test (uname, num) VALUES ('Jen', 25);

SELECT uname
    , CAST(min(num) as varchar(255)) + ' - ' + CAST(max(num) as varchar(255)) AS NumRange
FROM (
    SELECT uname, num - ROW_NUMBER() OVER (PARTITION BY uname ORDER BY num) groupnum, num
    FROM dbo.Test
    ) t
GROUP BY uname, groupnum;
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明

这是@AaronBertrand 提供的示例代码

;WITH cte as (
    SELECT uname
        , min(num) As MinNum
        , CAST(min(num) as varchar(255)) + ' - ' + CAST(max(num) as varchar(255)) AS NumRange
    FROM (
        SELECT uname, num - ROW_NUMBER() OVER (PARTITION BY uname ORDER BY num) groupnum, num
        FROM dbo.Test
        ) t
    GROUP BY uname, groupnum
    )
SELECT DISTINCT uname
    , STUFF((
        (
            SELECT ', ' + NumRange
            FROM cte as cte1
            WHERE cte.uname = cte1.uname
            ORDER BY cte1.MinNum
            FOR XML PATH, TYPE
        ).value('.[1]','VARCHAR(255)')
    ), 1, 2, '') as NumRange
FROM cte;
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明

STUFF此处用于,从结果中删除前导。它通过用零长度 string 替换连接的 NumRange 中的前两个前导字符来实现''

  • [剩下的路](http://sqlfiddle.com/#!3/79bdbd/1)。 (5认同)