2010-06-25 117 views
2

我有以下几点:旋转和汇总数据

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 

问:是否有生产在Microsoft SQL Server 2005以下输出的方法吗?

Pages 1-4 = 100 Copies, 5-5 = 50 Copies, 6-6 = 25 Copies 
+1

你想怎么处理的差距? IE:INSERT INTO @PrintJob(PageNumber,Copies)VALUES(7,100)'..or,是不允许发生的? – 2010-06-25 21:04:14

回答

6

假设差距就不会发生,用途:

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 

...会给你:

pages 
------- 
1-4 = 100 Copies 
5-5 = 50 Copies 
6-6 = 25 Copies 
0
select '1-4 = '+ 
    cast(SUM(case when PageNumber between 1 and 4 then Copies else 0 end) as varchar(10))+ 
' Copies , '+ 
    '5-5 = '+ 
    cast(SUM(case when PageNumber =5 then Copies else 0 end) as varchar(10))+' Copies , '+ 
    '6-6 = '+ 
    cast(SUM(case when PageNumber =6 then Copies else 0 end) as varchar(10))+' Copies' 
    from @PrintJob 
+0

Joseph, 我很感谢您回答我的问题。你知道我使用的例子只是为了说明一种可能的情况,对吗? – 2010-06-28 14:04:03

5

没有与上层溶液一个小问题。如果添加此示例代码:

INSERT INTO @PrintJob(PageNumber,Copies) VALUES(7,100) 

你会得到这样的:

pages 
------ 
1-7 = 100 Copies 
5-5 = 50 Copies 
6-6 = 25 Copies 

困难的部分是确定哪些是由序列中的副本值的变化来确定不同的组。

我的建议如下。它由T-SQL挑战赛冠军Neeraj Mathur的代码进行了修改。这里是链接:

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 
+0

谢谢!我认为ORDER BY子句解决了这个问题。 – 2010-06-28 14:05:14