Reputation: 753
if I have a result returned as follows:
pkTestInstanceID Percent1 Count1 Percent2 Count2
1 25 1 75 3
2 50 2 50 2
Is there a way so it pivots in such format:
pkTestInstanceID Percent Count
1 25 1
1 75 3
2 50 2
2 50 2
Sorry if this question is totally misguided. I'm not super clear on the pivoting process. Thanks for any help. EDIT I should probably have noted that the Percent1, Count1, Percent2 etc columns are created based off of another column (stackposition). So if stackposition has 4 rows then the percent and count will go up to percent4 count4. Is a pivot or union still possible without the knowledge of the exact number of percent and count columns in the result set.
EDIT 2: It gets a bit more complicated now...
I now realize that I have to include another item in my select statement (fkBandID). For each bandID there is a stackposition as stated above, so for bandID 96 the stackposition is 4, for 97 the stackposition is 3, for 98 the stackposition is 2 etc. so I want the result set to look as follows:
fkBandID pkTestInstanceID Band_Percent Band_Count StackPosition (not included but there for for visual example)
96 265 2 1 4
97 265 4 2 3
98 265 34 17 2
99 265 59 29 1
Here is what the creation of my second query looks like after the initial result set is brought back and with the bandID being selected including the new bandID. This is from Pradeep's answer. http://gyazo.com/091ece1a4a1334c0f2546bccb8a6b8da
This is what the result set looks like, so as you can see there are 4 rows being created for each bandID. Is there anyway to fix this and make it look as I displayed above in the cross apply that Pradeep helped me with? Or any other solution? http://gyazo.com/cd19634a1201362ac3aa4546f15373c9
Sorry I'm super nooby with SQL. Let me know if more info is needed.
EDIT 3
(N'DECLARE @strYearIds nvarchar(100)
SET @strYearIds = ''' + @strYearIds + N'''
DECLARE @strDemoCodeIds nvarchar(100)
SET @strDemoCodeIds = ''' + @strDemoCodeIds + N'''
DECLARE @intRosterSetId int
SET @intRosterSetId = ' + CONVERT(nvarchar, @intRosterSetId) + N'
DECLARE @intSchoolId int
SET @intSchoolId = ' + CONVERT(nvarchar, @intSchoolId) + N'
DECLARE @intTeachId int
SET @intTeachId = ' + CONVERT(nvarchar, @intTeachId) + N'
DECLARE @intGradeId int
SET @intGradeId = ' + CONVERT(nvarchar, @intGradeId) + N'
DECLARE @intDeptId int
SET @intDeptId = ' + CONVERT(nvarchar, @intDeptId) + N'
DECLARE @intCourseId int
SET @intCourseId = ' + CONVERT(nvarchar, @intCourseId) + N'
DECLARE @intPeriodId int
SET @intPeriodId = ' + CONVERT(nvarchar, @intPeriodId) + N'
DECLARE @strTestInstId nvarchar(100)
SET @strTestInstId = ''' + @strTestInstId + N'''
DECLARE @intTestTypeId int
SET @intTestTypeId = ' + CONVERT(nvarchar, @intTestTypeId) + N'
DECLARE @strSubIds nvarchar(100)
SET @strSubIds = ''' + @strSubIds + N'''
DECLARE @bitIsStrand bit
SET @bitIsStrand = ' + CONVERT(nvarchar, @bitIsStrand) + N'
DECLARE @intPerfLevelReportId int
SET @intPerfLevelReportId = ' + CONVERT(nvarchar, @intPerfLevelReportId) +
N' DECLARE @tempTests TABLE (id int)
INSERT INTO @tempTests
exec SPGetStudentTests_Local_MTI @strDemoCodeIds, @strYearIds, @intSchoolId, @intTeachId, @intGradeId,
@intRosterSetId, @intPeriodId, @intDeptId, @intCourseId, @strTestInstId, @intTestTypeId
DECLARE @tempSubs TABLE (id int)
IF @bitIsStrand = 1
BEGIN
INSERT INTO @tempSubs
SELECT pkTestSubjectID FROM MM_Test_Subjects WHERE fkCSTStrandID /*= @intSubID*/ IN (SELECT number FROM itot(@strSubIds, N'','')) AND fkTestTypeID = @intTestTypeId
END
ELSE
BEGIN
INSERT INTO @tempSubs
SELECT number FROM itot(@strSubIds, N'','')--VALUES (@intSubId)
END
SELECT bands.pkPerformanceLevelReportBandID AS ''fkBandID'', TestInstances.pkTestInstanceID AS ''TestInstanceID'', StudentScores_Subject.fkTest_SubjectID AS ''TestSubjectID'', '
+ @cols +
N'INTO ##tempTable FROM StudentScores_Subject
INNER JOIN StudentTests ON StudentScores_Subject.fkStudentTestID = StudentTests.pkStudentTestID
INNER JOIN TestInstances ON TestInstances.pkTestInstanceID = StudentTests.fkTestInstanceID
INNER JOIN CAHSEE_TestPeriods ON CAHSEE_TestPeriods.pkTestPeriodID = TestInstances.fkTestPeriodID
INNER JOIN PerformanceLevelReportBands bands ON bands.fkPerformanceLevelReportID = @intPerfLevelReportId
LEFT JOIN MMARS_Web_TestInfo_California.dbo.PerfLevelReportBandCutScores cutScores ON cutScores.fkPerformanceLevelReportBandID = bands.pkPerformanceLevelReportBandID
AND cutScores.fkGradeID = @intGradeId
AND cutScores.fkTestSubjectID IN (SELECT id FROM @tempSubs)
INNER JOIN PerfLevelReportBandComponents bandComponents ON bandComponents.fkPerformanceLevelReportBandID = bands.pkPerformanceLevelReportBandID
AND((bandComponents.ScoreValue = StudentScores_Subject.ScoreValue) OR
((CAST(StudentScores_Subject.ScoreValue AS INT) BETWEEN bandComponents.minScore and bandComponents.maxScore)
OR
(CAST(StudentScores_Subject.ScoreValue AS INT) BETWEEN cutScores.minScore and cutScores.maxScore))
)
RIGHT JOIN MM_SchoolYears ON MM_SchoolYears.pkSchoolYearID = TestInstances.fkSchoolYearID
WHERE MM_SchoolYears.pkSchoolYearID IN (SELECT number FROM itot(@strYearIds, N'',''))
AND bands.fkPerformanceLevelReportID = @intPerfLevelReportId
AND StudentScores_Subject.fkStudentTestID IN (SELECT id FROM @tempTests)
AND StudentScores_Subject.fkScoreTypeID = bandComponents.fkScoreTypeID
AND StudentScores_Subject.fkTest_SubjectID IN (SELECT id FROM @tempSubs)
--AND((bandComponents.ScoreValue = StudentScores_Subject.ScoreValue) OR
--(StudentScores_Subject.ScoreValue BETWEEN bandComponents.minScore and bandComponents.maxScore) OR
--(StudentScores_Subject.ScoreValue BETWEEN cutScores.minScore and cutScores.maxScore))
GROUP BY bands.pkPerformanceLevelReportBandID, TestInstances.pkTestInstanceID, StudentScores_Subject.fkTest_SubjectID
ORDER BY bands.pkPerformanceLevelReportBandID, TestInstances.pkTestInstanceID, StudentScores_Subject.fkTest_SubjectID')
The @cols variable is as follows:
DECLARE @cols NVARCHAR(MAX)
SELECT @cols = STUFF(( SELECT DISTINCT TOP 100 PERCENT ', SUM(CASE WHEN bands.StackPosition = ''' + STR(b.StackPosition, 1) + ''' THEN 1 ELSE 0 END) * 100.0/ CASE WHEN COUNT(pkStudentScoreID) = 0 THEN 1 ELSE COUNT(pkStudentScoreID) END AS ''Percent_' + STR(b.StackPosition, 1) + ''', SUM(CASE WHEN bands.StackPosition = ''' + STR(b.StackPosition, 1) + ''' THEN 1 ELSE 0 END) AS ''Count_' + STR(b.StackPosition, 1) + ''''
FROM PerformanceLevelReportBands AS b
WHERE b.fkPerformanceLevelReportID = @intPerfLevelReportId
ORDER BY ', SUM(CASE WHEN bands.StackPosition = ''' + STR(b.StackPosition, 1) + ''' THEN 1 ELSE 0 END) * 100.0/ CASE WHEN COUNT(pkStudentScoreID) = 0 THEN 1 ELSE COUNT(pkStudentScoreID) END AS ''Percent_' + STR(b.StackPosition, 1) + ''', SUM(CASE WHEN bands.StackPosition = ''' + STR(b.StackPosition, 1) + ''' THEN 1 ELSE 0 END) AS ''Count_' + STR(b.StackPosition, 1) + ''''
FOR XML PATH('')
), 1, 2, '')
Upvotes: 1
Views: 105
Reputation: 93734
what you are looking for is Unpivot not pivot
CREATE TABLE #piv
(
pkTestInstanceID INT,
Percent1 INT,
Count1 INT,
Percent2 INT,
Count2 INT
)
INSERT INTO #piv
VALUES ( 1,25,1,75,3),
(2,50,2,50,2)
SELECT pkTestInstanceID,
[percent],
[count]
FROM #piv AS p
CROSS APPLY ( VALUES (Percent1,Count1),
(Percent2,Count2))
AS x([percent], [count]);
If you want this to work dynamically then below code should help you. For example i have kept no. of stackposition rows as 2 u can change it and check
DECLARE @stackposition INT=2,
@sql NVARCHAR(max),
@cnt INT=1
SET @sql =' SELECT pkTestInstanceID,
[percent],
[count]
FROM #piv AS p
CROSS APPLY ( VALUES '
WHILE @cnt <= @stackposition
BEGIN
SET @sql+='([Percent' + CONVERT(VARCHAR(10), @cnt)+ '],[Count' + CONVERT(VARCHAR(10), @cnt) + ']),'
SET @cnt+=1
END
SET @sql= LEFT(@sql, Len(@sql) - 1)
SET @sql+=') AS x([percent], [count])'
EXEC Sp_executesql
@sql
OUTPUT
pkTestInstanceID percent count
---------------- ------- -----
1 25 1
1 75 3
2 50 2
2 50 2
Upvotes: 2
Reputation: 77896
You don't really need to pivot
here. You can do a UNION
on the resultset as suggested by @bksi like below
select pkTestInstanceID, percent1 as [percent], count1 as count
from (
inner result set
) tab
UNION
select pkTestInstanceID, percent2, count2
from (
inner result set
) tab1
Upvotes: 0