Can someone please help me to achieve this query: I need to carry all the IDs for each letter that has the value 1:
Asked
Active
Viewed 2,413 times
1
-
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 Answers
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

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
-
1Just 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
-
1Put 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