2017-04-26 48 views
1

我使用SQL Server 2012。我有數據的兩個大表,如下:無損耗Transpone SQL列在性能

tableProjects

| ID | Name  | 
| 1 | Project1 | 
| 2 | Project2 | 
| … | …  | 
| N | ProjectN | 

tableHours(減小爲簡單起見列數)(數處理階段減少到3爲簡單起見)的

| ProjectID | ProcessStage | Hours | 
| 1   | 1   | 10 | 
| 1   | 2   | 20 | 
| 1   | 3   | 30 | 
| 2   | 1   | 40 | 
| 2   | 2   | 50 | 
| 2   | 3   | 60 | 
| …   | …   | …  | 
| N   | 1   | 70 | 
| N   | 2   | 80 | 
| N   | 3   | 90 | 

我需要選擇的方式,每個ProcessStage得到一個單獨的列這個數據,所以我transpone這個數據,象這樣:

SELECT p.ID, p.Name, 
(SELECT Hours FROM tableHours WHERE ProcessStage = 1 AND ProjectID = p.ID) AS Hours1, 
(SELECT Hours FROM tableHours WHERE ProcessStage = 2 AND ProjectID = p.ID) AS Hours2, 
(SELECT Hours FROM tableHours WHERE ProcessStage = 3 AND ProjectID = p.ID) AS Hours3 
FROM tableProjects p 

而且其實我得到了我想要的:

| ID | Name  | Hours1 | Hours2 | Hours3 | 
| 1 | Project1 | 10  | 20  | 30  | 
| 2 | Project2 | 40  | 50  | 60  | 
| … | …  | …  | …  | …  | 
| N | ProjectN | 70  | 80  | 90  | 

但在我的情況下的性能是非常重要的,所以我想如果有這樣做的更有效的方式。如果你知道它,你能告訴我嗎?謝謝。

回答

1

使用條件聚集轉動你的數據:

select 
    p.id 
    , p.Name 
    , Hours1 = max(case when h.ProcessStage = 1 then h.Hours end) 
    , Hours2 = max(case when h.ProcessStage = 2 then h.Hours end) 
    , Hours3 = max(case when h.ProcessStage = 3 then h.Hours end) 
from tableProjects p 
    inner join tableHours h 
    on h.Projectid = p.id 
group by p.id, p.Name 

你可以使用動態SQL來自動生成所需支點列,但因爲你說的性能是非常重要的,它可能是最好的硬如果可能的話,請編碼。

+0

考慮到tableProjects與多個表連接在一起,並且它有更多的自己的列可供選擇,比如說總共有10列。與我選擇此數據的方式相比,GROUP BY的所有這些列是否會降低總體生產力? –

+0

@ B.Sverediuk一點都沒有。但是因爲我沒有你的數據,你爲什麼不測試它並看看?檢查執行計劃和查詢統計時間和io。 – SqlZim

+0

我會試試你的方式並比較結果。無論哪種方式對我的數據更有效率都將被使用。謝謝。 –