将UNPIVOT与动态SQL结合使用

将UNPIVOT与动态SQL结合使用,sql,sql-server-2005,pivot,dynamic-sql,unpivot,Sql,Sql Server 2005,Pivot,Dynamic Sql,Unpivot,我有一个具有此架构的表: TBL结果 Question1 | Question2 | Question3 | etc | etc | Question240 | 在这些列中,值可以是以下值: 1, 2, 3, 4, N, M DECLARE @colsUnpivot AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @colsUnpivot = STUFF((SELECT distinct ','+ quotename(c.colu

我有一个具有此架构的表:

TBL结果

Question1 | Question2 | Question3 | etc | etc | Question240 |
在这些列中,值可以是以下值:

1, 2, 3, 4, N, M
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 '+@colsUnpivot+'
          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);
我需要像这样呈现数据:

| 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            |
这将生成以下结果集:

| 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,因为我想不出任何其他方法来实现这一点。我尝试过各种各样的解题方法,但似乎没有任何进展

Beofre任何人都认为这是一个多么糟糕的设计,我知道,这是我继承的东西,如果不重写第三方应用程序,它是无法更改的

如果有人能想出一个更好的标题,请编辑


谢谢。

根据您提供的信息,您需要将答案值转换为列。因为您的答案是一个静态值(1、2、3、4、N、M),所以您可以将这些值硬编码到查询中

不过,您仍然需要使用动态SQL取消填充正确的列。代码将类似于以下内容:

1, 2, 3, 4, N, M
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 '+@colsUnpivot+'
          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);
看。这就产生了一个结果:

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

你能发布一些额外的样本数据吗?什么将成为新的列标题以及每个标题下的值是什么?@BlueFoots我已经添加了我到目前为止所拥有的,
计数
是正确的,但我需要将
答案
的值作为列。根据当前查询生成的结果集,您希望最终结果是什么?@BlueFoots请看我问题中的第三个代码块,很抱歉造成混淆。列:
QuestionNumber,1,2,3,4,N,M
您显示的内容不清楚,您希望
答案
值作为列标题。什么是一个有多个答案的问题?您想要什么作为列标题?请详述细节,因为不太清楚。是否希望所有不同的答案都作为新列?如果你有1000个不同的答案呢。非常感谢,太好了。你能解释一下PIVOT和UNPIVOT吗?我以前使用过UNPIVOT,但我不明白在这种情况下,如何将两者结合使用。@JackPettinger UNPIVOT基本上是将数据从多列规范化为多行。将结果放入多行后,您希望将每个答案的总计数显示为一列。PIVOT使用聚合函数
count()
,然后提供要转换为列的值列表,这是答案列表。希望这能有所帮助,如果你还有其他问题,请告诉我。