2009-03-30 23 views
5

Estoy buscando una forma de recorrer las columnas de una tabla para generar una salida como se describe a continuación.Loop through columns SQL

La tabla que se parece a:

 
ID Name  OPTION1 OPTION2 OPTION3 OPTION4 OPTION5 
1 MyName1 1  0  1  1  0 
2 MyName2 0  0  1  0  0 

Y la salida que se parece a:

 
MyName1 -> OPTION1, OPTION3, OPTION4 
MyName2 -> OPTION3 

cualquier instrucción de hacer esto simplemente sería muy apreciada. De lo contrario, supongo que tendré que usar un cursor o una tabla temporal ... El motor de base de datos es MSSQL. La razón por la que estoy formateando a nivel de base de datos es alimentar su salida en un entorno programable limitado.

Actualización: la salida puede ser en cualquier forma, una cadena o filas de cadenas.

Actualización: ¿Sería la forma de lograrlo construyendo una cadena usando @str = @str + ...?

Actualización: Cambié la salida ... esto debería ser más fácil.

Gracias!

+0

¿Tiene un número fijo de columnas? (también "Option4 -> MyName1"?) –

+0

Hola Ian, sí, supongamos que tenemos un número fijo de columnas. –

+0

Creo que no está claro cuál debería ser el resultado. ¿Quieres tomar una mesa y generar cadenas de texto? Una solución de "tabla dinámica" daría como resultado un conjunto de resultados u otra tabla. –

Respuesta

4

Pues bien, en el caso de un número conocido de columnas, se puede hacer:

SELECT 
    MyName + " ->" 
    + case OPTION1 when 1 then ' OPTION1' else '' end 
    + case OPTION2 when 1 then ' OPTION2' else '' end 
    + ... 
FROM 
Table 

Si las columnas son desconocidos cuando se crea la consulta - yo probablemente todavía ir de esa manera con un poco de SQL creada dinámicamente. La ventaja es que el código probablemente hace lo que quiere y es muy simple.

+0

No estoy seguro de por qué no pensé en eso ... Gracias. –

4

Es posible que desee echar un vistazo a las tablas dinámicas.

+0

Derecha, las tablas pivote deben ser utilizables. Comprobando para ver si hay otras ideas nuevas sobre una metodología que no conozco. –

2

Ya que no entra en las necesidades específicas de por qué quiere ser capaz de hacer esto, no puede ser cierto , pero generalmente cuando veo este tipo de preguntas, hay dos cosas que pienso:

  1. Necesita normalizar su base de datos. Tal vez "Option1", "Option2", etc. no tienen nada en común, pero también hay una buena posibilidad de que sean un grupo repetitivo dentro de su mesa.

  2. Manejar los problemas de visualización en la capa de visualización de la aplicación, es decir, la interfaz, no la base de datos.

Como dije, puede que esto no se aplique en su caso por alguna razón específica, pero parece que por lo que leí de su pregunta.

+0

Derecha, Tom. La razón por la que trato de formatear a nivel de la base de datos es poder enviar el resultado directamente en un informe en el que no tengo mucha flexibilidad de scripting. –

+0

Sí, ese sería uno de esos casos en que este tipo de cosas se vuelve necesario. Continua. ;) –

1

Si utiliza la tabla dinámica, debe asegurarse de que todas sus columnas "Opción" tengan el mismo tipo y longitud de datos.

que sugeriría la siguiente respuesta:


IF NOT EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME  
= 'TABLE1') 
create table table1 
(
    name nvarchar(50),  
    colvalue nvarchar(50) 
) 
else 
    truncate table table1 

declare @table nvarchar(50) 
set @table = 'yourtable' 

declare @column table 
(
    ID integer identity, 
    colname nvarchar(20) 
) 


insert into @column 
SELECT c.name FROM sys.tables t 
JOIN sys.columns c ON t.Object_ID = c.Object_ID 
WHERE t.Name = @table 
and c.name in ('Option1','Option2','Option3','Option4','Option5') 

declare @minID integer, @maxID integer 
declare @cmd nvarchar(max) 
declare @col nvarchar(20) 
declare @SQLStr nvarchar(max) 

select @minID = MIN(ID), @maxID= MAX(ID) 
from @column 

while @minID <= @maxID 
begin 
    select @col = colname 
    from @column 
    where ID = @minID 

    set @SQLStr =  
    'insert into table1 (name, colvalue) 
    select name,' + @col + ' 
    from ' + @table + ' 
    where ' + @col + ' <> 0'  

    exec(@SQLStr) 

    set @minID = @minID + 1 
end 

select distinct name, STUFF(
(SELECT ',' + a.colvalue AS [text()] 
from Table1 a 
where a.name = b.name 
Order by a.colvalue 
for xml PATH('')),1,1,'' ) AS Comments_Concatenated 
from Table1 b 
group by name, colvalue 
ORDER BY name 

Sólo hay que modificar el @table poniendo en su nombre de la tabla y la lista de la columna que necesita antes de insret en @ columna.

Independientemente del tipo de datos que tenga, funcionará correctamente.