2015-09-04 117 views
-1

過去已經很好地回答了這個問題(herehere)。看來,我仍然無法讓我知道這個關鍵的東西(我也沒有使用它很長一段時間)。如何在SQL Server 2008中透視數據以獲得期望的結果?

所以希望有人(再次)能告訴我如何將數據放到所需的格式:

鑑於數據:

ID | Label | Occurences | RangeBegin | RangeEnd | Unit 
---+-------+------------+------------+----------+-------- 
1 | One | 0   | -1000  | 0  | m 
1 | One | 5   | 0   | 10  | m 
1 | One | 8   | 10   | 20  | m 
1 | One | 6   | 20   | 30  | m 
1 | One | 15   | 30   | 40  | m 
1 | One | 0   | 40   | 1000  | m 
2 | One | 0   | -1000  | 0  | m 
2 | One | 2   | 0   | 10  | m 
2 | One | 13   | 10   | 20  | m 
2 | One | 27   | 20   | 30  | m 
2 | One | 5   | 30   | 40  | m 
2 | One | 0   | 40   | 1000  | m 
1 | Two | 0   | -1000  | 0  | kg 
1 | Two | 4   | 0   | 2  | kg 
1 | Two | 6   | 2   | 4  | kg 
1 | Two | 1   | 4   | 6  | kg 
1 | Two | 0   | 6   | 1000  | kg 
2 | Two | 0   | -1000  | 0  | kg 
2 | Two | 8   | 0   | 2  | kg 
2 | Two | 1   | 2   | 4  | kg 
2 | Two | 3   | 4   | 6  | kg 
2 | Two | 0   | 6   | 1000  | kg 

期望的結果:

ID | One | OneRangeBegin | OneRangeEnd | OneUnit | Two | TwoRangeBegin | TwoRangeEnd | TwoUnit 
---+-----+---------------+-------------+---------+------+---------------+-------------+---------- 
1 | 0 | -1000   | 0   | m  | 0 | -1000   | 0   | kg 
1 | 5 | 0    | 10   | m  | 4 | 0    | 2   | kg 
1 | 8 | 10   | 20   | m  | 6 | 2    | 4   | kg 
1 | 6 | 20   | 30   | m  | 1 | 4    | 6   | kg 
1 | 15 | 30   | 40   | m  | 0 | 6    | 1000  | kg 
1 | 0 | 40   | 1000  | m  | null | null   | null  | null 
2 | 0 | -1000   | 0   | m  | 0 | -1000   | 0   | kg 
2 | 2 | 0    | 10   | m  | 8 | 0    | 2   | kg 
2 | 13 | 10   | 20   | m  | 1 | 2    | 4   | kg 
2 | 27 | 20   | 30   | m  | 3 | 4    | 6   | kg 
2 | 5 | 30   | 40   | m  | 0 | 6    | 1000  | kg 
2 | 0 | 40   | 1000  | m  | null | null   | null  | null 

而且爲了使它的工作更容易一點,我把上面的數據放在SqlFiddle

+1

兩個表你需要看看逆轉置和支點。你有沒有嘗試過任何代碼來獲得解決方案? – Taryn

+1

發佈您的查詢嘗試,並發現它出了什麼問題。錯誤或意外結果? –

回答

2

我認爲它可以做這樣的事情來實現:

  1. 拆表基於標籤
  2. 排名上標識的每個表的分區和基於RangeBegin安排它。ROW_NUMBER() OVER(PARTITION BY ID ORDER BY RangeBegin)
  3. 全部加入的ID和排名

SQL Fiddle

SELECT 
A.ID AS ID 
,A.Occurences AS One 
,A.RangeBegin AS OneRangeBegin 
,A.RangeEnd AS OneRangeEnd 
,A.Unit AS OneUnit 
,B.Occurences AS Two 
,B.RangeBegin AS TwoRangeBegin 
,B.RangeEnd AS TwoRangeEnd 
,B.Unit AS TwoUnit 


FROM 
(select 
*, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY RangeBegin) Rank 
from 
AvailableData 
wHere Label = 'One') A 
FULL JOIN 
(select 
*, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY RangeBegin) Rank 
from 
AvailableData 
Where Label = 'Two') B 
ON A.ID = B.ID 
AND A.Rank = B.Rank 
ORDER BY ISNULL(A.ID, B.ID), ISNULL(A.Rank, B.Rank) 
1

我一直有困難纏繞樞軸以及我的頭。出於這個原因,我傾向於使用聚合CASE方法而不是PIVOT,因爲我覺得更容易推理(而且更靈活)。基本上你需要將問題分解成多個步驟。

  1. 確定如何將數據分組 - 例如,通過ID,RangeBegin,rangeEnd的
  2. 確定所有列將是什麼,他們將在那裏進行採購
  3. 寫的聚合CASE語句每一列 - 注意:您必須確保每個輸出是明確的,或者你會得到缺失的結果

聚合CASE樞紐的總體佈局是這樣的:

SELECT 
    grouped columns 
    ,MAX(CASE WHEN condition THEN column END) as ColumnName 
    ,... 
FROM 
    Table 
GROUP BY grouped columns 

關鍵是上述條件將確定每列的來源。因此,例如,列OneUnit顯然來自於Unit列當LabelOne,所以這將是:

MAX(CASE WHEN Label='One' THEN Unit END) as OneUnit 

這將是很容易申請到您的具體的例子,但沒有明顯的將One到Two的行關聯在一起,因爲您將不同的範圍組合在一起。您需要確定一個明確的規則,以便在構建實際的數據透視查詢之前將各行組合在一起,這應該非常簡單(由於一組和兩組之間的範圍不同,因此當前會生成額外的行):

select 
    D.ID, D.RangeBegin, D.RangeEnd 
    ,MAX(CASE WHEN Label='One' THEN D.Occurences END) as One 
    ,MAX(CASE WHEN Label='One' THEN D.RangeBegin END) as OneRangeBegin 
    ,MAX(CASE WHEN Label='One' THEN D.RangeEnd END) as OneRangeEnd 
    ,MAX(CASE WHEN Label='One' THEN D.Unit END) as OneUnit 
    ,MAX(CASE WHEN Label='Two' THEN D.Occurences END) as Two 
    ,MAX(CASE WHEN Label='Two' THEN D.RangeBegin END) as TwoRangeBegin 
    ,MAX(CASE WHEN Label='Two' THEN D.RangeEnd END) as vRangeEnd 
    ,MAX(CASE WHEN Label='Two' THEN D.Unit END) as TwoUnit 
from 
    AvailableData D 
group by 
    D.ID, D.RangeBegin, D.RangeEnd 
相關問題