2013-06-05 2 views
-1

У меня есть таблица с этой схемой:Использования UNPIVOT с динамическим SQL

tblResults

Question1 | Question2 | Question3 | etc | etc | Question240 | 

В этих значениях столбцов может быть представлена ​​следующим образом:

1, 2, 3, 4, N, M 

Мне нужно представляет данные, подобные этому:

| QuestionNumber | 1 | 2 | 3 | 4 | N | M | 
------------------------------------------ 
| Question1  | 53| 27| 10| 5 | 2 | 3 | 
| etc   | 20| 40| 32| 8 | 0 | 0 | <-- These values being % (but I can do the calculation later). 
| etc   | 

Мне нужно уметь контролировать количество строк, которые будет выводить результирующий набор. Я сделал это, выполнив следующие (3 колонки только):

DECLARE @cname VARCHAR(MAX) 
SELECT @cname = STUFF((
    SELECT ', ' + COLUMN_NAME 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE (TABLE_NAME = 'tblResults') AND (ORDINAL_POSITION BETWEEN 8 AND 10) 
    FOR XML PATH(''), TYPE).value('.', 'varchar(max)'), 1,1,'') 

DECLARE @sql NVARCHAR(MAX) 
SET @sql = 'SELECT Answers, CASE WHEN Answer = '''' THEN ''N'' ELSE Answer END AS Answer, COUNT(Answer) AS Total 
      FROM (
       SELECT '[email protected]+' 
       FROM tblResults 
       WHERE (something = ''006'') AND (somethingElse = ''ABC'') 
       ) AS MyTable 
      UNPIVOT (Answer FOR Answers IN ('[email protected]+')) AS MyUnPivot 
      GROUP BY Answers, Answer 
      ORDER BY Answers, Answer' 

exec sp_executesql @sql 

Это приводит следующий результирующий набор:

| Answers | Answer | Total | 
---------------------------- 
|Question1| 1 | 12474 | 
|Question1| 2 | 188 | 
|Question1| 3 | 200 | 
|Question1| 4 | 5  | 
|Question1| N | 0  | 
|Question1| M | 142 | 
|Question2| 1 | 14521 | 
|etc  |  |  | 
|etc  |  |  | 

Поэтому мой план состоял в том, чтобы использовать динамический SQL, как я не могу думать о любой другой способ сделать это. Я пробовал различные методы UNPIVOT, но я не могу добиться какого-либо прогресса.

Beofre, кто-нибудь предлагает, какой ужасный дизайн это, я знаю, это то, что я унаследовал, и его нельзя изменить, не переписывая стороннее приложение.

Если кто-нибудь может подумать о лучшем названии, отредактируйте его.

Спасибо.

+0

Можете ли вы разместить дополнительные данные образца? Что становится заголовками новых столбцов и каковы значения под каждым заголовком? – Taryn

+0

@bluefeet Я добавил то, что у меня до сих пор, 'COUNT' правильные, но мне нужно получить значения' Ответ' в виде столбцов. –

+0

Основываясь на наборе результатов, который производит ваш текущий запрос, каков вам конечный результат? – Taryn

ответ

1

Основываясь на информации, которую вы предоставили, вам нужно PIVOT значения ответов в столбцы. Поскольку ваши ответы являются статическим значением (1, 2, 3, 4, N, M), вы можете жестко закодировать эти значения в своем запросе.

Вам все равно придется использовать динамический SQL, чтобы раскрыть правильные столбцы. Код будет аналогичен следующему:

DECLARE @colsUnpivot AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @colsUnpivot = STUFF((SELECT distinct ','+ quotename(c.column_name) 
        from INFORMATION_SCHEMA.COLUMNS as C 
        where (TABLE_NAME = 'tblResults') and 
         (c.ORDINAL_POSITION BETWEEN 3 AND 5) 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query 
    = 'select questionNumber, [1], [2], [3], [4], [N], [M] 
    from 
    (
     select questionNumber, answer 
     from 
     (
      select '[email protected]+' 
      from tblResults 
     ) x 
     unpivot 
     (
      answer 
      for questionNumber in ('+ @colsunpivot +') 
     ) u 
    ) d 
     pivot 
     (
     count(answer) 
     for answer in ([1], [2], [3], [4], [N], [M]) 
    ) piv' 

exec(@query); 

См SQL Fiddle with Demo. Это дает следующие результаты:

| QUESTIONNUMBER | 1 | 2 | 3 | 4 | N | M | 
------------------------------------------ 
|  Question3 | 1 | 1 | 1 | 1 | 1 | 1 | 
|  Question4 | 1 | 0 | 1 | 2 | 1 | 1 | 
|  Question5 | 1 | 1 | 1 | 0 | 1 | 2 | 
+0

спасибо, безупречный. Можете ли вы объяснить PIVOT и UNPIVOT, я раньше использовал UNPIVOT, но я не понимаю, как это работает в этом сценарии, используя эти два вместе. –

+0

@JackPettinger UNPIVOT в основном нормализует ваши данные из нескольких столбцов в несколько строк.После того, как вы получите результат в несколько строк, вы хотите отобразить общий счетчик для каждого ответа в виде столбца. PIVOT использует агрегатную функцию 'count()', а затем вы предоставляете список значений, которые вы хотите преобразовать в столбцы, это ваш список ответов. Надеюсь, что это поможет, дайте мне знать, если у вас есть другие вопросы. – Taryn