5

I'm looking for a way to loop through the columns of a table to generate an output as described below.

The table looks like that:

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

And the output looks like that:

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

Any directions of doing this simply would be greatly appreciated. Otherwise, I suppose I'll have to use a cursor or a temporary table... The database engine is MSSQL. The reason I'm doing formatting at the database level is to feed its output into a limited programmable environment.

Update: the ouput can by in any form, a string or rows of strings.

Update: Would the be a way to accomplish that by building a string using @str = @str + ... ?

Update: I changed the output... this should be easier.

Thanks!

Wadih M.
  • 12,810
  • 7
  • 47
  • 57

6 Answers6

4

Well, in case of a known number of columns, you can do:

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

If columns are unknown when you create the query - I'd probably still go that way with some dynamically created SQL. The advantage is that the code probably does what you wants and is very simple.

user76035
  • 1,526
  • 1
  • 10
  • 12
3

You might want to have a look at PIVOT Tables.

John Boker
  • 82,559
  • 17
  • 97
  • 130
  • Right, pivot tables should be usable. Checking to see if there are other fresh ideas about a methodology I'm not aware of. – Wadih M. Mar 30 '09 at 14:21
2

Since you don't go into the specific needs of why you want to be able to do this I can't be certain, but usually when I see this kind of question there are two things that I think of:

  1. You need to normalize your database. Maybe "Option1", "Option2" etc. have nothing in common, but there is also a good chance that they are a repeating group within your table.

  2. Handle display issues in the display layer of your application - i.e. the front end, not the database.

As I said, maybe these don't apply in your case for some specific reason, but it seems like it from what I've read of your question.

Tom H
  • 46,766
  • 14
  • 87
  • 128
  • Right, Tom. The reason I'm trying to do formatting at the database level is to be able to feed the output directly in a report where I don't have much scripting flexibility. – Wadih M. Mar 30 '09 at 15:56
  • Yep, that would be one of those cases where this kind of thing becomes necessary. Carry on. ;) – Tom H Mar 30 '09 at 18:17
1

If using pivot table, you must make sure all of your "Option" columns have the same data type and length.

I would suggest the following answer:


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

You just have to modify the @table by putting in your table name and the list of the column you need before insret into @column.

No matter what data type you are, it will working fine.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
shh
  • 91
  • 1
1

You could build a dynamic statement using the system catalog:

http://msdn.microsoft.com/en-us/library/ms189082.aspx

nearly_lunchtime
  • 12,203
  • 15
  • 37
  • 42