2016-09-25 204 views
0

我有以下數據,我想透視並根據透視結果得到數字。T-SQL數據透視表數據透視結果

DECLARE @tempMusicSchoolStudent TABLE 
(school VARCHAR(50), 
studentname VARCHAR(50), 
instrumentname VARCHAR(255), 
expertise INT) 

INSERT INTO @tempMusicSchoolStudent(school, studentname, instrumentname, expertise) 
SELECT 'Foster','Matt','Guitar','10' 
UNION 
SELECT 'Foster','Jimmy','Guitar','5' 
UNION 
SELECT 'Foster','Jimmy','Keyboard','8' 
UNION 
SELECT 'Foster','Ryan','Keyboard','9' 
UNION 
SELECT 'Midlothean','Kyle','Keyboard','10' 
UNION 
SELECT 'Midlothean','Mary','Guitar','4' 
UNION 
SELECT 'Midlothean','Mary','Keyboard','7' 

原始數據:

enter image description here

我想結果看起來像下面的數據....

enter image description here

我用得到這個數據下面的sql查詢。這個查詢的問題是我有一個動態數量的工具(爲了簡單起見,我在這個例子中只顯示了2個)。我想使用數據透視表,因爲它會更乾淨的動態SQL。否則,我必須動態地將每個樂器的表格自動加入到自己的表格中。

SELECT 
    t.school, t.instrumentname, t.expertise, 
    t1.instrumentname, t1.expertise, 
    COUNT(DISTINCT t.studentname) [DistinctStudentCount] 
FROM 
    @tempMusicSchoolStudent t 
LEFT JOIN 
    @tempMusicSchoolStudent t1 ON t1.school = t.school 
           AND t1.studentname = t.studentname 
           AND t.instrumentname <> t1.instrumentname 
GROUP BY 
    t.school, t.instrumentname, t.expertise, t1.instrumentname, t1.expertise 
ORDER BY 
    t.school, t.instrumentname, t.expertise, t1.instrumentname, t1.expertise 

如果有人不是動態左側的接合部表到它本身將不勝感激我如何能在一個更清潔的方式做到這一點的任何想法。謝謝。

+0

你的輸出中row1和row3有什麼不同? – p2k

+1

這裏沒有區別,但它是數據的預期模式。如果我可以刪除那些很棒的重複,但現在用戶可以很好地完成這些工作,因爲他們希望完全連接數據。 – mgmedick

回答

0

這是我一直在尋找,解決我不得不使用逆轉置+支點。

我一直在努力的事情是爲正在旋轉的列選擇多個值,而不是最大值。

因此,在這種情況下,我想在給定的「儀器專業知識」欄下找到多個「專家」號碼。不僅僅是該儀器的最大專業知識。

理解解決方案的第一個關鍵是,pivot語句在被選中的列上進行隱式分組。因此,爲了在您的透視列下實現多個值,您必須通過包含某種類型的dense_rank/rank/row_number來保持您正在分組的列的完整性。這基本上代表了您正在旋轉的列的值的變化,然後通過數據透視表包含在隱式組中,這會導致在透視列中獲取多個值,而不僅僅是最大值。

所以在下面的代碼中,「expertisenum」列保留了專業知識數據的完整性。

DECLARE @tempMusicSchoolStudent TABLE 
(school VARCHAR(50), 
studentname VARCHAR(50), 
instrumentname VARCHAR(255), 
expertise INT) 

INSERT INTO @tempMusicSchoolStudent(school, studentname, instrumentname, expertise) 
SELECT 'Foster','Matt','Guitar','10' 
UNION 
SELECT 'Foster','Jimmy','Guitar','5' 
UNION 
SELECT 'Foster','Jimmy','Keyboard','8' 
UNION 
SELECT 'Foster','Ryan','Keyboard','9' 
UNION 
SELECT 'Midlothean','Kyle','Keyboard','10' 
UNION 
SELECT 'Midlothean','Mary','Guitar','4' 
UNION 
SELECT 'Midlothean','Mary','Keyboard','7' 



SELECT school, [Guitar expertise], [Keyboard expertise], COUNT(*) [Count] 
FROM 
(
    SELECT school,[expertiseNum], 
    CASE WHEN [Columns]='expertise' THEN instrumentname + ' expertise' 
     END [Columns1], [Values] AS [Values1] 
    FROM 
    (
     SELECT school, studentname, instrumentname, DENSE_RANK() OVER(PARTITION BY school,instrumentname ORDER BY expertise) AS [expertiseNum], 
     CONVERT(VARCHAR(255),expertise) AS [expertise] 
     FROM @tempMusicSchoolStudent 
    ) x 
    UNPIVOT (
     [Values] FOR [Columns] IN ([expertise]) 
    ) unpvt 
) p 
PIVOT (
    MAX([Values1]) FOR [Columns1] IN ([Guitar expertise], [Keyboard expertise]) 
) pvt 
GROUP BY school,[Guitar expertise], [Keyboard expertise] 
1

你只需要有條件聚集:

SELECT t.school, t.instrumentname, t.expertise, t.instrumentname, 
     COUNT(DISTINCT t.studentname) as DistinctStudentCount 
FROM @tempMusicSchoolStudent t 
GROUP BY t.school, t.instrumentname, t.expertise, t.instrumentname; 

您有NULL值的行。這些來自哪裏完全不清楚。你的問題集中在一些「旋轉」的概念上,看起來你只需要聚合。但它並不能解釋NULL行的來源。

+0

它是我需要的一種笛卡爾結果。 因此,例如,我得到的結果的第一行是給我每個不同的學生在寄養,同時彈奏吉他和鍵盤與5吉他的專業知識和8鍵盤的專業知識的計數。 然後結果將落在吉他的所有專業知識的培養和交叉加入,這將在寄養的所有鍵盤專業知識,並獲得這些儀器的專業知識發生的不同學生的數量。 – mgmedick

+0

所以第二排的結果是空的是因爲有一個孩子在寄養誰只彈吉他,而不是鍵盤,與10的專業知識。 – mgmedick

1

您可以嘗試使其適用於多功能樂器。 Refer

;with cte 
as 
(
SELECT * from 
(SELECT * FROM @tempMusicSchoolStudent t) x 
PIVOT 
(MAX(expertise) FOR instrumentname in ([Guitar], [Keyboard])) y 
) 

SELECT school, studentname, 
expertise = case when Guitar is not null then 'Guitar' else NULL end, 
Guitar AS instrumentname, 
expertise = case when Keyboard is not null then 'Keyboard' else NULL end, 
Keyboard AS instrumentname, 
count(distinct studentname) AS [DistinctStudentCount] 
from cte 
group by school,studentname, Guitar, Keyboard 

OUTPUT:

Foster   Jimmy Guitar 5  Keyboard 8  1 
Foster   Matt Guitar 10 NULL  NULL 1 
Foster   Ryan NULL NULL Keyboard 9  1 
Midlothean  Kyle NULL NULL Keyboard 10  1 
Midlothean  Mary Guitar 4  Keyboard 7  1