[英]Pivoting SQL Server result set
如果我返回的结果如下:
pkTestInstanceID Percent1 Count1 Percent2 Count2
1 25 1 75 3
2 50 2 50 2
有没有一种方法可以将其转换为以下格式:
pkTestInstanceID Percent Count
1 25 1
1 75 3
2 50 2
2 50 2
抱歉,这个问题完全被误导了。 我对数据透视过程不太清楚。 谢谢你的帮助。 编辑我可能应该已经注意到,Percent1,Count1,Percent2等列是基于另一列(堆栈位置)创建的。 因此,如果stackposition有4行,则百分比和计数将上升到percent4 count4。 在不知道结果集中确切的百分比和计数列的情况下,仍然可以进行数据透视或联合。
编辑2:现在变得更加复杂了...
现在,我意识到我必须在我的选择语句(fkBandID)中包含另一个项目。 对于每个bandID,都有一个如上所述的堆栈位置,因此对于bandID 96,堆栈位置为4,对于97,堆栈位置为3,对于98,堆栈位置为2,依此类推,所以我希望结果集如下所示:
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
这是在恢复初始结果集并选择bandID包括新bandID之后创建第二个查询的样子。 这是来自Pradeep的回答。 http://gyazo.com/091ece1a4a1334c0f2546bccb8a6b8da
这就是结果集的样子,因此您可以看到为每个bandID创建了4行。 无论如何,有什么办法可以解决这个问题,并使它看起来像我在十字架上显示的那样,适用于Pradeep帮助我的应用? 或其他解决方案? http://gyazo.com/cd19634a1201362ac3aa4546f15373c9
抱歉,我对SQL非常满意。 让我知道是否需要更多信息。
编辑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')
@cols变量如下:
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, '')
您正在寻找的是Unpivot不枢轴
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]);
如果您希望它动态地工作,那么下面的代码应该可以为您提供帮助。 例如,我一直没有。 的stackposition行为2 u可以更改它并检查
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
您实际上并不需要在这里pivot
。 您可以按如下所示由@bksi建议在结果集上执行UNION
select pkTestInstanceID, percent1 as [percent], count1 as count
from (
inner result set
) tab
UNION
select pkTestInstanceID, percent2, count2
from (
inner result set
) tab1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.