Есть небольшая проблема с верхним решением.Если вы добавите это в пример кода:
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(7,100)
Вы получите это:
pages
------
1-7 = 100 Copies
5-5 = 50 Copies
6-6 = 25 Copies
Трудная часть идентифицирует различные группы, которые определяются изменением значения Copiesв последовательности.
Мое предложение ниже.Он модифицирован из кода победителя конкурса T-SQL Нираджа Матюра.Вот ссылка:
http://beyondrelational.com/blogs/tc/archive/2009/11/27/tsql-challenge-13-solution-by-neeraj-mathur-and-other-tsql-heros.aspx
Код:
declare @PrintJob TABLE (
PageNumber Int,
Copies Int
)
/* Load the table */
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(1,100)
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(2,100)
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(3,100)
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(4,100)
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(5,50)
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(6,25)
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(7,100)
/* Set up the string for the final result */
DECLARE @str VARCHAR(MAX)
SET @str = 'Pages '
/* Build a cte with all rows plus a row number for each row */
;WITH cte1 AS (
SELECT
PageNumber,
Copies,
ROW_NUMBER() OVER (ORDER BY PageNumber) AS RowNumber
FROM @PrintJob
),
/*
Build a second, recursive cte that increments a
group number each time the Copies value changes
*/
cte2 AS (
SELECT
PageNumber,
Copies,
RowNumber,
1 AS GroupID
FROM cte1
WHERE RowNumber = 1
UNION ALL
SELECT
c1.PageNumber,
c1.Copies,
c1.RowNumber,
CASE WHEN c1.Copies <> c2.Copies THEN GroupID + 1 ELSE GroupID END AS GroupID
FROM cte2 c2
INNER JOIN cte1 c1
ON c1.RowNumber = c2.RowNumber + 1
)
/*
Get the min and max values for each Group
of pages that repeats the Copies value
and assign that to a string
*/
SELECT
@str = @str
+ CONVERT(VARCHAR(100), StartPage) + '-'
+ CONVERT(VARCHAR(100), EndPage) + ' = ' +
+ CONVERT(VARCHAR(100), Copies) + ' Copies, '
FROM (
SELECT
GroupID,
MIN(PageNumber) AS StartPage,
MAX(PageNumber) AS EndPage,
Copies
FROM cte2
GROUP BY
GroupID,
Copies
) t1
ORDER BY GroupID
/* Get the string but cut off the last comma */
SELECT LEFT(@str, LEN(@str)-1)
Результат:
------
Pages 1-4 = 100 Copies, 5-5 = 50 Copies, 6-6 = 25 Copies, 7-7 = 100 Copies