我有一个包含此架构的表:
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 '+@cname+'
FROM tblResults
WHERE (something = ''006'') AND (somethingElse = ''ABC'')
) AS MyTable
UNPIVOT (Answer FOR Answers IN ('+@cname+')) 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 :(得分:1)
根据您提供的信息,您需要将答案值分配到列中。由于您的答案是静态值(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 '+@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);
见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 |