[英]Formatting SQL Output (Pivot)
這是在SQL Server 2008上運行。
無論如何,我有銷售數據,我可以編寫一個查詢來使輸出看起來像這樣:
id | Name | Period | Sales
1 | Customer X | 2013/01 | 50
1 | Customer X | 2013/02 | 45
目前,運行此數據后,我正在重新排列后面代碼中的數據,以便最終輸出如下所示:
id | Name | 2013/01 | 2013/02
1 | Customer X | 50 | 40
問題是:
我考慮過只提取必要的數據(客戶ID - 它們如何連接在一起,期間和銷售數字),然后運行單獨的查詢以獲取其他數據。 雖然它看起來並不高效,但這是一種可能性。
另一個,我認為應該是最好的選擇,就是重寫我的查詢以繼續執行我當前的代碼所做的事情,並將數據轉移到一起,這樣客戶數據永遠不會重復,我沒有移動很多不必要的數據。
為了更好地展示我正在使用的內容,讓我們假設這些表:
地址
id | HouseNum | Street | Unit | City | State
顧客
id | Name |
銷售
id | Period | Sales
所以我想在客戶ID上加入這些表格,顯示所有地址數據,假設用戶輸入“2012/01 - 2012/12”,我可以將其翻譯成2012 / 01,02012 / 02 ... 2012/12在我的代碼背后,在執行之前輸入查詢,所以我有可用的。
我希望它看起來像是:
id | Name | HouseNum | Street | City | State | 2012/01 | 2012/02 | ... | 2012/12
1 | X | 100 | Main St. | ABC | DEF | 30 | | ... | 20
(2012/02年度沒有該客戶的銷售數據 - 如果任何數據為空白我希望它是一個空白字符串“”,而不是NULL)
我意識到我可能不會以最好的方式解釋這個,所以請告訴我,我會添加更多信息。 謝謝!
編輯:哦,最后一件事。 是否可以在最后添加Min,Max,Avg和Total列,它們總結了所有的數據? 在后面的代碼上做這件事並不是什么大不了的事,但是更多的sql server可以為我做得更好,imo!
編輯:還有一個,期間在表中作為“2013/01”等,但我想將它們重命名為“2013年1月”等,如果它不是太復雜?
您可以實現PIVOT函數將數據從行轉換為列。 您可以使用以下內容來獲得結果:
select id,
name,
HouseNum,
Street,
City,
State,
isnull([2013/01], 0) [2013/01],
isnull([2013/02], 0) [2013/02],
isnull([2012/02], 0) [2012/02],
isnull([2012/12], 0) [2012/12],
MinSales,
MaxSales,
AvgSales,
TotalSales
from
(
select c.id,
c.name,
a.HouseNum,
a.Street,
a.city,
a.state,
s.period,
s.sales,
min(s.sales) over(partition by c.id) MinSales,
max(s.sales) over(partition by c.id) MaxSales,
avg(s.sales) over(partition by c.id) AvgSales,
sum(s.sales) over(partition by c.id) TotalSales
from customer c
inner join address a
on c.id = a.id
inner join sales s
on c.id = s.id
) src
pivot
(
sum(sales)
for period in ([2013/01], [2013/02], [2012/02], [2012/12])
) piv;
請參閱SQL Fiddle with Demo 。
如果要將未知數量的period
值轉換為列,則必須使用動態SQL來獲取結果:
DECLARE @cols AS NVARCHAR(MAX),
@colsNull AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(period)
from Sales
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsNull = STUFF((SELECT distinct ', IsNull(' + QUOTENAME(period) + ', 0) as '+ QUOTENAME(period)
from Sales
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id,
name,
HouseNum,
Street,
City,
State,' + @colsNull + ' ,
MinSales,
MaxSales,
AvgSales,
TotalSales
from
(
select c.id,
c.name,
a.HouseNum,
a.Street,
a.city,
a.state,
s.period,
s.sales,
min(s.sales) over(partition by c.id) MinSales,
max(s.sales) over(partition by c.id) MaxSales,
avg(s.sales) over(partition by c.id) AvgSales,
sum(s.sales) over(partition by c.id) TotalSales
from customer c
inner join address a
on c.id = a.id
inner join sales s
on c.id = s.id
) x
pivot
(
sum(sales)
for period in (' + @cols + ')
) p '
execute(@query)
請參閱SQL Fiddle with Demo 。 這些給出了結果:
| ID | NAME | HOUSENUM | STREET | CITY | STATE | 2012/02 | 2012/12 | 2013/01 | 2013/02 | MINSALES | MAXSALES | AVGSALES | TOTALSALES |
---------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | Customer X | 100 | Maint St. | ABC | DEF | 0 | 20 | 50 | 45 | 20 | 50 | 38 | 115 |
| 2 | Customer Y | 108 | Lost Rd | Unknown | Island | 10 | 0 | 0 | 0 | 10 | 10 | 10 | 10 |
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.