2012-08-16 22 views
5

Tengo datos de cuestionario en SQL Server 2008, que quiero transponer a una matriz.
Vi varias publicaciones sobre el mismo tema, pero simplemente no me hago pivotar.Columnas dinámicas pivote, sin agregación

dadas son las tablas siguientes:

Question table

Answer table

Customer table

las columnas:
[CustomerID], [QuestionName_1], .., [QuestionName_n] < - dinámica número de columnas de interrogación)
Los datos:
CustomerID, Answer_1, .., Answer_n

El código para recuperar las columnas:

DECLARE @columns VARCHAR(8000) 

SELECT @columns = COALESCE(@columns + ',[' + cast(QuestionName as varchar) + ']', 
'[' + cast(QuestionName as varchar)+ ']') 
FROM Answer A 
INNER JOIN Question Q ON A.QuestionID = Q.QuestionID 
INNER JOIN Customer C ON A.CustomerID = C.CustomerID 
GROUP BY Q.QuestionName 

SET @columns = '[CustomerID],' + @columns 

DECLARE @query VARCHAR(8000) 
SET @query = 'Some PIVOT query without aggregation' 

EXECUTE(@query) 

La idea inicial fue tomado de consulta pivots with dynamic columns.

¿Se puede hacer y cómo sería la consulta pivotante?
pd: no quiero usar la clasificación con un número máximo de columnas.

Saludos,

Michel

Respuesta

15

sí se puede realizar una cruzada dinámica. A veces es más fácil trabajar con la consulta PIVOT usando primero una versión estática para que pueda ver cómo aparecerán la consulta y los resultados. Luego transforma la consulta en una versión dinámica.

Aquí es un ejemplo de una versión dinámica vs estática de una consulta:

estático (SQL Fiddle):

select * 
from 
(
    select u.userid, 
     u.fname, 
     u.lname, 
     u.mobile, 
     r.question, 
     r.choice 
    from users u 
    left join results r 
     on u.questionid = r.questionid 
     and u.choiceid = r.choiceid 
) x 
pivot 
(
    min(choice) 
    for question in([are you], [from]) 
) p 

dinámico (SQL Fiddle):

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.question) 
      FROM results c 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT userid, fname, lname, mobile, ' + @cols + ' from 
      (
       select u.userid, 
        u.fname, 
        u.lname, 
        u.mobile, 
        r.question, 
        r.choice 
       from users u 
       left join results r 
        on u.questionid = r.questionid 
        and u.choiceid = r.choiceid 
      ) x 
      pivot 
      (
       min(choice) 
       for question in (' + @cols + ') 
      ) p ' 


execute(@query) 

Si es posible proporcione más detalles sobre su estructura de tabla actual y luego algunos datos de muestra. Deberíamos poder ayudarlo a crear la versión que necesitaría para su situación.

Como dije, a veces es más fácil comenzar con una versión estática, donde codifica las columnas que primero necesita para transformar, luego pasa a la versión dinámica.

+0

En su ejemplo, ¿qué tipo de datos tiene el campo 'choice'? Tengo un campo varchar que contiene la respuesta a la pregunta. –

+0

Es un 'varchar' si nos fijamos en el SQL Fiddle, se mostrará la estructura de la tabla. – Taryn

+0

Lo tengo trabajando, con MIN (QuestionName). ¡No esperaba eso! Gracias por su ayuda Azul :). –