簡體   English   中英

格式化SQL輸出(Pivot)

[英]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

問題是:

  1. 日期(YYYY / MM)范圍是來自用戶的輸入。
  2. 如果用戶選擇更多輸出(例如,地址,以及與該客戶相關的大量其他可能字段),則該信息在每一行中都是重復的。 如果你在5年以上的時間內每行10-15個項目,對於50000多個用戶來說,這會導致內存不足的問題,而且效率也很低。

我考慮過只提取必要的數據(客戶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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM