Phi*_*enn 2 sql t-sql sql-server
我有以下内容:
declare @PrintJob TABLE (
PageNumber Int,
Copies Int
)
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)
SELECT * FROM @PrintJob
Run Code Online (Sandbox Code Playgroud)
问:有没有办法在Microsoft SQL Server 2005中生成以下输出?
Pages 1-4 = 100 Copies, 5-5 = 50 Copies, 6-6 = 25 Copies
Run Code Online (Sandbox Code Playgroud)
假设不能发生差距,请使用:
SELECT CAST(MIN(pj.pagenumber) AS VARCHAR(max)) +'-'+ CAST(MAX(pj.pagenumber) AS VARCHAR(max)) +' = '+ CAST(pj.copies AS VARCHAR(max)) +' Copies' AS pages
FROM PRINTJOB pj
GROUP BY pj.copies
ORDER BY pj.copies DESC
Run Code Online (Sandbox Code Playgroud)
...会给你:
pages
-------
1-4 = 100 Copies
5-5 = 50 Copies
6-6 = 25 Copies
Run Code Online (Sandbox Code Playgroud)
顶级解决方案存在轻微问题.如果将其添加到示例代码中:
INSERT INTO @PrintJob(PageNumber,Copies) VALUES(7,100)
Run Code Online (Sandbox Code Playgroud)
你会得到这个:
pages
------
1-7 = 100 Copies
5-5 = 50 Copies
6-6 = 25 Copies
Run Code Online (Sandbox Code Playgroud)
困难的部分是识别由序列中Copies值的变化确定的不同组.
我的建议如下.它是从T-SQL挑战赛冠军Neeraj Mathur的代码中修改而来的.链接在这里:
码:
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)
Run Code Online (Sandbox Code Playgroud)
结果:
------
Pages 1-4 = 100 Copies, 5-5 = 50 Copies, 6-6 = 25 Copies, 7-7 = 100 Copies
Run Code Online (Sandbox Code Playgroud)