Sql server SQL concat整数并将其分组为从到
我是stackoverflow的新手,但我的问题一直没有解决 我有一个SQL表,它看起来像这样:Sql server SQL concat整数并将其分组为从到,sql-server,tsql,Sql Server,Tsql,我是stackoverflow的新手,但我的问题一直没有解决 我有一个SQL表,它看起来像这样: +-------+------------+ | col1 | col2 | +-------+------------+ | 1 | 1 | | 1 | 2 | | 1 | 3 | | 1 | 4 | | 1 | 6 | +-------+--------
+-------+------------+
| col1 | col2 |
+-------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 6 |
+-------+------------+
我不知道如何获得以下结果集:
+-------+------------+
| col1 |SerialNumber|
+-------|------------+
| 1 | 1 to 4, 6 |
+--------------------+
使用XML路径,我可以得到以下结果:
+-------+------------+
| col1 |SerialNumber|
+-------|------------+
| 1 | 1,2,3,4,6, |
+--------------------+
这是我对它的查询:
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
如果我的问题已经被问到了,我很抱歉。我也缺少这个主题的关键词。测试数据:
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)
XML路径的变量为:
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
结果:
col1 SerialNumber
1 1 to 4,6 to 9,11,13
2 3 to 5,7
解决方案:
-- Table creation
CREATE TABLE #ValuesTable (
Col1 int,
Col2 int
)
INSERT INTO #ValuesTable VALUES (1, 1)
INSERT INTO #ValuesTable VALUES (1, 2)
INSERT INTO #ValuesTable VALUES (1, 3)
INSERT INTO #ValuesTable VALUES (1, 4)
INSERT INTO #ValuesTable VALUES (1, 6)
INSERT INTO #ValuesTable VALUES (2, 1)
INSERT INTO #ValuesTable VALUES (2, 2)
INSERT INTO #ValuesTable VALUES (2, 3)
INSERT INTO #ValuesTable VALUES (2, 4)
INSERT INTO #ValuesTable VALUES (2, 6)
INSERT INTO #ValuesTable VALUES (2, 7);
INSERT INTO #ValuesTable VALUES (2, 10);
-- Find sequences
WITH
TableStart AS (
SELECT t.Col1, t.Col2, ROW_NUMBER() OVER (ORDER BY t.Col1, t.Col2) AS RN
FROM #ValuesTable t
LEFT JOIN #ValuesTable b ON (t.Col1 = b.Col1) AND (t.Col2 = b.Col2 + 1)
WHERE (b.Col2 IS NULL)
),
TableEnd AS (
SELECT t.Col1, t.Col2, ROW_NUMBER() OVER (ORDER BY t.Col1, t.Col2) AS RN
FROM #ValuesTable t
LEFT JOIN #ValuesTable b ON (t.Col1 = b.Col1) AND (t.Col2 = b.Col2 - 1)
WHERE (b.Col2 IS NULL)
),
TableSequences AS (
SELECT
TableStart.Col1 AS Col1,
CASE
WHEN (TableStart.Col2 <> TableEnd.Col2) THEN CONVERT(nvarchar(max), TableStart.Col2) + N' to ' + CONVERT(nvarchar(max), TableEnd.Col2)
ELSE CONVERT(nvarchar(max), TableStart.Col2)
END AS Sequence
FROM TableStart
LEFT JOIN TableEnd ON (TableStart.RN = TableEnd.RN)
)
-- Select with group concatenation
SELECT
t1.Col1,
(
SELECT t2.Sequence + N', '
FROM TableSequences t2
WHERE t2.Col1 = t1.Col1
ORDER BY t2.Col1
FOR XML PATH('')
) SerialNumber
FROM (SELECT DISTINCT Col1 FROM TableSequences) t1
使用CTE作为每个序列和组串联的起始值和结束值的另一种可能方法:
T-SQL:
-- Table creation
CREATE TABLE #ValuesTable (
Col1 int,
Col2 int
)
INSERT INTO #ValuesTable VALUES (1, 1)
INSERT INTO #ValuesTable VALUES (1, 2)
INSERT INTO #ValuesTable VALUES (1, 3)
INSERT INTO #ValuesTable VALUES (1, 4)
INSERT INTO #ValuesTable VALUES (1, 6)
INSERT INTO #ValuesTable VALUES (2, 1)
INSERT INTO #ValuesTable VALUES (2, 2)
INSERT INTO #ValuesTable VALUES (2, 3)
INSERT INTO #ValuesTable VALUES (2, 4)
INSERT INTO #ValuesTable VALUES (2, 6)
INSERT INTO #ValuesTable VALUES (2, 7);
INSERT INTO #ValuesTable VALUES (2, 10);
-- Find sequences
WITH
TableStart AS (
SELECT t.Col1, t.Col2, ROW_NUMBER() OVER (ORDER BY t.Col1, t.Col2) AS RN
FROM #ValuesTable t
LEFT JOIN #ValuesTable b ON (t.Col1 = b.Col1) AND (t.Col2 = b.Col2 + 1)
WHERE (b.Col2 IS NULL)
),
TableEnd AS (
SELECT t.Col1, t.Col2, ROW_NUMBER() OVER (ORDER BY t.Col1, t.Col2) AS RN
FROM #ValuesTable t
LEFT JOIN #ValuesTable b ON (t.Col1 = b.Col1) AND (t.Col2 = b.Col2 - 1)
WHERE (b.Col2 IS NULL)
),
TableSequences AS (
SELECT
TableStart.Col1 AS Col1,
CASE
WHEN (TableStart.Col2 <> TableEnd.Col2) THEN CONVERT(nvarchar(max), TableStart.Col2) + N' to ' + CONVERT(nvarchar(max), TableEnd.Col2)
ELSE CONVERT(nvarchar(max), TableStart.Col2)
END AS Sequence
FROM TableStart
LEFT JOIN TableEnd ON (TableStart.RN = TableEnd.RN)
)
-- Select with group concatenation
SELECT
t1.Col1,
(
SELECT t2.Sequence + N', '
FROM TableSequences t2
WHERE t2.Col1 = t1.Col1
ORDER BY t2.Col1
FOR XML PATH('')
) SerialNumber
FROM (SELECT DISTINCT Col1 FROM TableSequences) t1
注意事项:
-- Table creation
CREATE TABLE #ValuesTable (
Col1 int,
Col2 int
)
INSERT INTO #ValuesTable VALUES (1, 1)
INSERT INTO #ValuesTable VALUES (1, 2)
INSERT INTO #ValuesTable VALUES (1, 3)
INSERT INTO #ValuesTable VALUES (1, 4)
INSERT INTO #ValuesTable VALUES (1, 6)
INSERT INTO #ValuesTable VALUES (2, 1)
INSERT INTO #ValuesTable VALUES (2, 2)
INSERT INTO #ValuesTable VALUES (2, 3)
INSERT INTO #ValuesTable VALUES (2, 4)
INSERT INTO #ValuesTable VALUES (2, 6)
INSERT INTO #ValuesTable VALUES (2, 7);
INSERT INTO #ValuesTable VALUES (2, 10);
-- Find sequences
WITH
TableStart AS (
SELECT t.Col1, t.Col2, ROW_NUMBER() OVER (ORDER BY t.Col1, t.Col2) AS RN
FROM #ValuesTable t
LEFT JOIN #ValuesTable b ON (t.Col1 = b.Col1) AND (t.Col2 = b.Col2 + 1)
WHERE (b.Col2 IS NULL)
),
TableEnd AS (
SELECT t.Col1, t.Col2, ROW_NUMBER() OVER (ORDER BY t.Col1, t.Col2) AS RN
FROM #ValuesTable t
LEFT JOIN #ValuesTable b ON (t.Col1 = b.Col1) AND (t.Col2 = b.Col2 - 1)
WHERE (b.Col2 IS NULL)
),
TableSequences AS (
SELECT
TableStart.Col1 AS Col1,
CASE
WHEN (TableStart.Col2 <> TableEnd.Col2) THEN CONVERT(nvarchar(max), TableStart.Col2) + N' to ' + CONVERT(nvarchar(max), TableEnd.Col2)
ELSE CONVERT(nvarchar(max), TableStart.Col2)
END AS Sequence
FROM TableStart
LEFT JOIN TableEnd ON (TableStart.RN = TableEnd.RN)
)
-- Select with group concatenation
SELECT
t1.Col1,
(
SELECT t2.Sequence + N', '
FROM TableSequences t2
WHERE t2.Col1 = t1.Col1
ORDER BY t2.Col1
FOR XML PATH('')
) SerialNumber
FROM (SELECT DISTINCT Col1 FROM TableSequences) t1
在SQL Server 2005、2012、2016上进行了测试。因此,这基本上是一个缺口和孤岛问题,再加上字符串聚合。您可能需要先搜索“间隙和孤岛”。谢谢,间隙和孤岛描述了我的问题。我缺少关键字。您使用什么版本的SQLServer?我们使用MSSQL 2016。