不使用循环获取特定结果

Nul*_*ter 5 sql-server-2005 sql-server

我有一个表格,其中的数据对于单个用户来说是这样的

ID - 号码 - 子号码 - 姓名

1 101 201101 Jack
2 101 201102 Jack
3 101 201103 Jack
4 101 201107 Jack
5 101 201111 Jack
6 101 201112 Jack
7 101 201113 Jack
8 101 201161 Jack
9 101 201162 Jack
10 101 201163 Jack
11 101 201164 Jack
12 101 201165 Jack

我想得到这样的记录 without using any kind of loop.

号码 - 姓名 - 子号码

101 Jack (201101-201103, 201107, 201111-201113, 201161-201165)

目前我能够以这种形式获取记录

号码 - 姓名 - 子号码

101 Jack (201101,201102,201103, 201107, 201111.201112,201113, 201161,201162,201163,201164,201165)

获得上结果的查询是

SELECT  Number, Name
,STUFF((SELECT ', ' + CAST(SubNumber AS VARCHAR(50)) [text()]
     FROM [Table] 
     WHERE Number= t.Number
     FOR XML PATH(''), TYPE)
    .value('.','NVARCHAR(MAX)'),1,2,' ') SubNumber
FROM [Table] t
GROUP BY Number,Name
having Number= '101'
Run Code Online (Sandbox Code Playgroud)

我完全被困在这里。任何形式的帮助将不胜感激。

Rob*_*ley 3

首先row_number()为组合添加一个值,因为我猜你不能指望ID没有间隙。

WITH NumberedRows AS (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY Number, Name ORDER BY SubNumber) AS RowNum
  FROM [Table]
)
Run Code Online (Sandbox Code Playgroud)

--现在将 RowNum 与 SubNumber 进行比较。当差异发生变化时,SubNumber 值的序列中就会出现间隙。

, Diffs AS (
  SELECT *, SubNumber - RowNum AS TheDiff
  FROM NumberedRows
)
, Ranges AS (
  SELECT Number, Name,
    MIN(SubNumber) AS StartRange, 
    MAX(SubNumber) AS EndRange
  FROM Diffs
  GROUP BY Number, Name, TheDiff
)
, RangeStrings AS (
  SELECT Number, Name, 
    CASE WHEN StartRange = EndRange 
         THEN CAST(StartRange AS VARCHAR(10))
         ELSE CAST(StartRange AS VARCHAR(10)) + '-' + CAST(EndRange AS VARCHAR(10))
    END AS RangeString
  FROM Ranges
)
Run Code Online (Sandbox Code Playgroud)

--然后按照你已经解决的那样进行串联。:)

SELECT ...
FROM RangeStrings;
Run Code Online (Sandbox Code Playgroud)