Buscando una solución elegante (o cualquier) para convertir columnas en filas.
Aquí hay un ejemplo: tengo una tabla con el siguiente esquema:
[ID] [EntityID] [Indicator1] [Indicator2] [Indicator3] ... [Indicator150]
Esto es lo que quiero obtener como resultado:
[ID] [EntityId] [IndicatorName] [IndicatorValue]
Y los valores del resultado serán:
1 1 'Indicator1' 'Value of Indicator 1 for entity 1'
2 1 'Indicator2' 'Value of Indicator 2 for entity 1'
3 1 'Indicator3' 'Value of Indicator 3 for entity 1'
4 2 'Indicator1' 'Value of Indicator 1 for entity 2'
Y así..
¿Esto tiene sentido? ¿Tiene alguna sugerencia sobre dónde buscar y cómo hacerlo en T-SQL?
sql
sql-server
tsql
unpivot
Sergei
fuente
fuente
Respuestas:
Puede usar la función UNPIVOT para convertir las columnas en filas:
Tenga en cuenta que los tipos de datos de las columnas que está desconectando deben ser los mismos, por lo que es posible que tenga que convertir los tipos de datos antes de aplicar la desconexión.
También puede usar
CROSS APPLY
con UNION ALL para convertir las columnas:Dependiendo de su versión de SQL Server, incluso podría usar CROSS APPLY con la cláusula VALUES:
Finalmente, si tiene 150 columnas para desconectar y no desea codificar la consulta completa, puede generar la instrucción sql usando SQL dinámico:
fuente
UNPIVOT
y / vs.APPLY
, esta publicación de blog de 2010 de Brad Schulz (y la continuación ) es (son) hermosas.bueno, si tienes 150 columnas, creo que UNPIVOT no es una opción. Entonces podrías usar el truco xml
sql fiddle demo
También podría escribir SQL dinámico, pero me gusta más xml: para el SQL dinámico debe tener permisos para seleccionar datos directamente de la tabla y eso no siempre es una opción.
ACTUALIZACIÓN
Como hay una gran llama en los comentarios, creo que agregaré algunos pros y contras de xml / dynamic SQL. Intentaré ser lo más objetivo posible y no mencionar la elegancia y la fealdad. Si tienes otros pros y contras, edita la respuesta o escribe comentarios
contras
pros
inserted
ydeleted
tablas dentro de su activador (no es posible con dinámico en absoluto);fuente
Solo para ayudar a los nuevos lectores, he creado un ejemplo para comprender mejor la respuesta de @ bluefeet sobre UNPIVOT.
fuente
Necesitaba una solución para convertir columnas en filas en Microsoft SQL Server, sin conocer los nombres de columna (utilizados en el desencadenador) y sin sql dinámico (sql dinámico es demasiado lento para usarlo en un activador).
Finalmente encontré esta solución, que funciona bien:
Como puede ver, convierto la fila a XML (Subconsulta, seleccione i, * para xml raw, esto convierte todas las columnas en una columna xml)
Luego CRUZ APLICO una función a cada atributo XML de esta columna, de modo que obtengo una fila por atributo.
En general, esto convierte las columnas en filas, sin conocer los nombres de las columnas y sin utilizar sql dinámico. Es lo suficientemente rápido para mi propósito.
(Editar: acabo de ver a Roman Pekar responder arriba, quién está haciendo lo mismo. Primero utilicé el gatillo sql dinámico con cursores, que era de 10 a 100 veces más lento que esta solución, pero tal vez fue causado por el cursor, no por el sql dinámico. De todos modos, esta solución es muy simple y universal, por lo que definitivamente es una opción).
Dejo este comentario en este lugar, porque quiero hacer referencia a esta explicación en mi publicación sobre el activador de auditoría completo, que puede encontrar aquí: https://stackoverflow.com/a/43800286/4160788
fuente
Puede obtener una lista de tablas que tiene recuentos de filas> 350. Puede ver en la lista de soluciones de la tabla como fila.
fuente
Solo porque no lo vi mencionado.
Si 2016+, aquí hay otra opción para desconectar dinámicamente los datos sin usar Dynamic SQL.
Ejemplo
Devoluciones
fuente