1

Can someone please help me to achieve this query: I need to carry all the IDs for each letter that has the value 1:

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
user3314399
  • 317
  • 4
  • 9
  • 23
  • Looks like you need to use SQL PIVOT\UNPIVOT, see if this helps http://stackoverflow.com/questions/3241450/sql-pivot-with-multiple-columns – user3193257 Mar 05 '14 at 17:17

3 Answers3

2

This is a two step process. First you need to unpivot your columns to rows:

SELECT  upvt.ID, Letters
FROM    T
        UNPIVOT
        (   Value
            FOR Letters IN ([A], [B], [C], [D], [E], [F])
        ) upvt
WHERE   upvt.Value = 1;

This gives:

ID  Letters
10  A
10  C
10  E
10  F
...

Then you need to Concatenate the ID's From this result:'

WITH Unpivoted AS
(   SELECT  upvt.ID, Letters
    FROM    T
            UNPIVOT
            (   Value
                FOR Letters IN ([A], [B], [C], [D], [E], [F])
            ) upvt
    WHERE   upvt.Value = 1
)
SELECT  u.Letters,
        IDs = STUFF((   SELECT  ', ' + CAST(u2.ID AS VARCHAR(10))
                        FROM    Unpivoted u2
                        WHERE   u.Letters = u2.Letters
                        FOR XML PATH(''), TYPE
                    ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM    Unpivoted u
GROUP BY u.Letters;

Which gives:

Letters IDs
A       10, 20, 50
B       20, 40
C       10, 20, 30, 40, 50
D       30, 40
E       10, 50
F       10, 20, 40

Example on SQL Fiddle

GarethD
  • 68,045
  • 10
  • 83
  • 123
  • Thank you so much. Where can I specify the value for the Letter columns. For instance the column name for A is Letter_A. How can I have it as "A" instead of the column name "Letter_A" in the result? – user3314399 Mar 05 '14 at 18:18
  • 1
    Just use a replace, where it says `SELECT u.Letters` use `SELECT Letters = REPLACE(u.Letters, 'Letter_', '')` – GarethD Mar 05 '14 at 19:37
  • AWESOME THANK YOU, last question. How can I insert this to a Temp table? it doesnt let me do it since the query is using "with". – user3314399 Mar 05 '14 at 19:42
  • 1
    Put the insert between the CTE and the SELECT - `WITH (...) INSERT TABLE (COLUMNS) SELECT. ..` – GarethD Mar 05 '14 at 20:54
0
select distinct 'A',
(select cast(id as varchar)+',' from letters where a=1 for xml path('')) ids
 from letters where a=1
union all 
select distinct 'B',
(select cast(id as varchar)+',' from letters where b=1 for xml path('')) ids
from letters where b=1
union all
select distinct 'C',
(select cast(id as varchar)+',' from letters where c=1 for xml path('')) ids
 from letters where c=1
union all 
select distinct 'D',
(select cast(id as varchar)+',' from letters where d=1 for xml path('')) ids
from letters where D=1
union all
select distinct 'E',
(select cast(id as varchar)+',' from letters where e=1 for xml path('')) ids
 from letters where e=1
union all 
select distinct 'F',
(select cast(id as varchar)+',' from letters where f=1 for xml path('')) ids
from letters where f=1
Jayvee
  • 10,670
  • 3
  • 29
  • 40
0

There are two problems here: First, the table is not normalized, so you really need to first do an extra step to create a temporary table that normalizes the data:

The first step:

select id, 'A' as letter
from mytable where a=1
union
select id, 'B'
from mytable where b=1
union
select id, 'C'
from mytable where c=1
union
select id, 'D'
from mytable where d=1
union
select id, 'E'
from mytable where e=1
union
select id, 'F'
from mytable where f=1

Then you need to get multiple IDs crammed into one field. You can do this with the (deceptively named) "For XML".

Something like:

select letter, id + ', ' as [text()] 
from 
(    
select id, 'A' as letter
from mytable where a=1
union
select id, 'B'
from mytable where b=1
union
select id, 'C'
from mytable where c=1
union
select id, 'D'
from mytable where d=1
union
select id, 'E'
from mytable where e=1
union
select id, 'F'
from mytable where f=1
) q
group by letter
for XML path(''))

I think that would work.

Jay
  • 26,876
  • 10
  • 61
  • 112