2012-06-11 35 views
5

Teniendo en cuenta las dos tablas de ejemplo aquí:SQL: Vista dinámica con los nombres de columna en base a los valores de columna en la tabla de origen

Entradas Tabla

ID User Description 

0 James This is a support ticket 
1 Fred This is a ticket too 

Propiedades Tabla

ID TicketID Label   Value 

0 0   Engineer  Scott 
1 1   Engineer  Dale 
2 0   Manu   Dell 
3 1   Manu   HP 
4 0   OS    Windows 
5 1   OS    Linux 

¿Cómo puedo llegar a una vista como esta:

ID User Description     Engineer Manu OS 

1 James This is a support ticket Scott  Dell Windows 
2 Fred This is a ticket too  Dale  HP  Linux 

Es importante tener en cuenta que la tabla de propiedades no siempre será la misma. Algunos "Tickets" pueden tener propiedades que otros no tienen.

¿Esto es posible?

+2

Las tablas de propiedades son el demonio. –

+0

@Jeremy también pueden codificar los nombres de propiedad como nombres de columna. Ambos tienen su lugar. –

+0

@ AaronBertrand, una vez más, no estoy en desacuerdo contigo ... pero cada vez que tengo que usar tablas de propiedades casi siempre tengo problemas de rendimiento, y por lo general son un dolor en el trasero para pivotar. –

Respuesta

11

Puede realizar esto con un PIVOT. Al hacer PIVOT puede hacerlo de dos maneras, con un Pivote estático que codificará las filas para transformar o un Pivote dinámico que creará la lista de columnas en tiempo de ejecución:

Pivote estático (Consulte SQL Fiddle for Demo):

select id, [user], [engineer], [manu], [OS] 
from 
(
    select t.id 
     , t.[user] 
     , p.ticketid 
     , p.label 
     , p.value 
    from tickets t 
    inner join properties p 
     on t.id = p.ticketid 
) x 
pivot 
(
    min(value) 
    for label in ([engineer], [manu], [OS]) 
) p 

O puede utilizar una cruzada dinámica (Ver SQL Fiddle for Demo):

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(p.label) 
        from tickets t 
        inner join properties p 
         on t.id = p.ticketid 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT id, [user], ' + @cols + ' from 
      (
       select t.id 
         , t.[user] 
         , p.ticketid 
         , p.label 
         , p.value 
        from tickets t 
        inner join properties p 
         on t.id = p.ticketid 
      ) x 
      pivot 
      (
       min(value) 
       for label in (' + @cols + ') 
      ) p ' 

execute(@query) 

Tanto consulta devolverá los mismos resultados.

+0

su primer ejemplo es considerablemente más complicado que el mío con exactamente los mismos resultados, y el segundo ... ¿sql dinámico? Antes de seguir esa ruta, creo que querrá asegurarse de que es un requisito y cómo se va a consumir la mesa. –

+0

Eres mi nuevo héroe. Quiero tener tus bebes. (Dynamic Pivot funciona EXACTAMENTE como lo necesito) –

+1

@JeremyHolovacs No estoy de acuerdo con que la primera sea más complicada que su versión con 3 combinaciones a la izquierda. En cuanto a la versión dinámica, el OP solicitó una versión dinámica de una consulta que sería flexible y eso es lo que proporcioné. Siempre hay otras formas de responder una pregunta, no dude en sugerir otra forma dinámica. :) – Taryn

Cuestiones relacionadas