2014-10-25 3 views
1

, если у меня есть результат, возвращаемый следующим образом:Pivoting SQL Server результирующего набор

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 

Извините, если этот вопрос совершенно ошибочный. Я не уверен в процессе поворота. Спасибо за любую помощь. EDIT Возможно, я должен был заметить, что столбцы Percent1, Count1, Percent2 и т. Д. Создаются на основе другого столбца (stackposition). Так что если stackposition имеет 4 строки, то процент и счет будут увеличиваться до процента4 count4. Является ли стержень или объединение все еще возможным без знания точного количества столбцов процента и количества в результирующем наборе.

EDIT 2: Это становится немного более сложным, теперь ...

Я теперь понимаю, что я должен включить еще один пункт в моем отборном заявлении (fkBandID). Для каждого полосового идентификатора существует положение штабеля, как указано выше, поэтому для 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. Это от ответа Прадипа. http://gyazo.com/091ece1a4a1334c0f2546bccb8a6b8da

Это то, что похоже на результат, так как вы можете видеть, что для каждого bandID создаются 4 строки. Нужно ли все-таки исправить это и заставить его выглядеть так, как я показал выше на кресте, чтобы помочь мне помогать Прадип? Или любое другое решение? http://gyazo.com/cd19634a1201362ac3aa4546f15373c9

Извините, что я супер nooby с SQL. Позвольте мне знать, нужна ли дополнительная информация.

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') 

Переменная @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, '') 
+1

Хм, если Percent1, Count1, Percent2 и count2 являются столбцы, которые вы можете использовать UNION с 2 запросами – bksi

+0

Какой из них конечный результат?я надеюсь, что это первый стол –

+0

Это не зависящий от поворота !! –

ответ

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 и может изменить его и проверить

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 

ВЫВОД

pkTestInstanceID percent count 
---------------- ------- ----- 
    1     25  1 
    1     75  3 
    2     50  2 
    2     50  2 
+0

Спасибо человек. Помогли кучу! – frontin

+0

@ RyanGray - Счастлив, это помогло у ура :) –

+0

Pradeep! Могу ли я получить дополнительную помощь? Все стало немного сложнее. Я добавил новую информацию в edit 2, если вы можете помочь с этим ... Спасибо man – frontin

0

Вы на самом деле не нужно pivot здесь. Вы можете сделать UNION на результирующем как предложено @bksi, как показано ниже

select pkTestInstanceID, percent1 as [percent], count1 as count 
from (
inner result set 
) tab 

UNION 

select pkTestInstanceID, percent2, count2 
from (
inner result set 
) tab1  
+0

Делает ли разница, если столбцы percent1 count1 peecent2 etc вычисляются исходя из количества строк в другом столбце. Например. Если есть 4 строки стекирования, то есть 4 процента и подсчет столбцов, поэтому я точно не знаю точно количество столбцов, пока не увижу его в наборе результатов. Разве союз по-прежнему возможен без этих знаний? – frontin

+0

UNION будет работать в соответствии с вашим опубликованным набором результатов (я имею в виду первый). Если в вашем размещенном вопросе есть что-то, то я не уверен. попробуйте и посмотрите, насколько это хорошо. – Rahul

Смежные вопросы