Columnas dinámicas dinámicas, sin agregación

Resuelto Michel van Engelen asked hace 12 años • 1 respuestas

Tengo datos de cuestionario en SQL Server 2008 que quiero transponer a una matriz.
Vi varias publicaciones sobre el mismo tema, pero no logro cambiar.

Se presentan las siguientes tablas:

Question table

Answer table

Customer table

Las columnas:
[CustomerID] , [QuestionName_1], .., [QuestionName_n]<- número dinámico de columnas de preguntas)
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 de consulta inicial se tomó de pivotes con columnas dinámicas .

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

Saludos,

michel

Michel van Engelen avatar Aug 16 '12 18:08 Michel van Engelen
Aceptado

Sí, puedes realizar un pivote dinámico. A veces es más fácil elaborar la PIVOTconsulta utilizando primero una versión estática para que pueda ver cómo aparecerán la consulta y los resultados. Luego transforme la consulta en una versión dinámica.

A continuación se muestra un ejemplo de una versión estática versus dinámica de una consulta:

Estático ( violín SQL ):

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 ( violín SQL ):

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 puede proporcionar más detalles sobre la estructura de su tabla actual y luego algunos datos de muestra. Deberíamos poder ayudarle a crear la versión que necesitaría para su situación.

Sin embargo, como dije, a veces es más fácil comenzar con una versión estática, donde codificas las columnas que necesitas transformar primero y luego pasas a la versión dinámica.

Taryn avatar Aug 16 '2012 11:08 Taryn