SQL concat整数并将它们与from分组

K. *_*ein 3 t-sql sql-server

我是stackoverflow的新手,但我坚持我的查询.

我有一个SQL表格看起来像这样:

+-------+------------+
| col1  |   col2     |
+-------+------------+
|   1   |     1      |
|   1   |     2      |
|   1   |     3      |
|   1   |     4      |
|   1   |     6      |
+-------+------------+
Run Code Online (Sandbox Code Playgroud)

我不知道如何获得以下结果集:

+-------+------------+
| col1  |SerialNumber|
+-------|------------+
|   1   | 1 to 4, 6  |
+--------------------+
Run Code Online (Sandbox Code Playgroud)

使用XML Path我可以得到:

+-------+------------+
| col1  |SerialNumber|
+-------|------------+
|   1   | 1,2,3,4,6, |
+--------------------+
Run Code Online (Sandbox Code Playgroud)

这是我的查询:

SELECT DISTINCT O.Col1, 
 (SELECT CAST(P.Col2 As varchar(5)) + ',' AS [text()] 
 FROM #Test P 
 WHERE P.Col1 = O.Col1 
 ORDER BY P.Col1 
 FOR XML PATH('')) AS 'SerialNumber'
 FROM #Test O
Run Code Online (Sandbox Code Playgroud)

如果我的问题已被提出,我很抱歉.我也缺少此主题的关键字.

Ser*_*hov 5

测试数据:

CREATE TABLE t(col1 int,col2 int)

INSERT t(col1,col2)VALUES
(1,1),(1,2),(1,3),(1,4),
(1,6),(1,7),(1,8),(1,9),
(1,11),
(1,13),

(2,3),(2,4),(2,5),
(2,7)
Run Code Online (Sandbox Code Playgroud)

一个变种FOR XML PATH:

SELECT col1,col2,outVal
INTO #temp
FROM
  (
    SELECT
      col1,
      col2,
      outVal,
      ISNULL(LEAD(outVal)OVER(PARTITION BY col1 ORDER BY col2),'') nextOutVal
    FROM
      (
        SELECT
          col1,
          col2,
          CASE
            WHEN col2-1=LAG(col2)OVER(PARTITION BY col1 ORDER BY col2) AND col2+1=LEAD(col2)OVER(PARTITION BY col1 ORDER BY col2)
            THEN 'to'
            ELSE CAST(col2 AS varchar(10))
          END outVal
        FROM t
      ) q
  ) q
WHERE outVal<>nextOutVal
ORDER BY col1,col2

SELECT
  t1.col1,
  REPLACE(STUFF(
    (
      SELECT ','+t2.outVal
      FROM #temp t2
      WHERE t2.col1=t1.col1
      ORDER BY t2.col2
      FOR XML PATH('')
    ),1,1,''),',to,',' to ') SerialNumber
FROM (SELECT DISTINCT col1 FROM #temp) t1

DROP TABLE #temp
Run Code Online (Sandbox Code Playgroud)

SQL Server 2017(with STRING_AGG)的变体:

SELECT
  col1,
  REPLACE(STRING_AGG(outVal,',')WITHIN GROUP(ORDER BY col2),',to,',' to ')
FROM
  (
    SELECT
      col1,
      col2,
      outVal,
      ISNULL(LEAD(outVal)OVER(PARTITION BY col1 ORDER BY col2),'') nextOutVal
    FROM
      (
        SELECT
          col1,
          col2,
          CASE
            WHEN col2-1=LAG(col2)OVER(PARTITION BY col1 ORDER BY col2) AND col2+1=LEAD(col2)OVER(PARTITION BY col1 ORDER BY col2)
            THEN 'to'
            ELSE CAST(col2 AS varchar(10))
          END outVal
        FROM t
      ) q
  ) q
WHERE outVal<>nextOutVal
GROUP BY col1
Run Code Online (Sandbox Code Playgroud)

结果:

col1  SerialNumber
1     1 to 4,6 to 9,11,13
2     3 to 5,7
Run Code Online (Sandbox Code Playgroud)