2010-06-25 90 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