Reputation: 89
I have a case statement which I am using to create a column from several columns, depending on the answer in each column. I need to show a new row for each time the answer is 1 in any of the columns, but at the moment it is only showing one row for the first one that matches.
Please see the code and examples. Thanks
I am using SQL Server 17 I am querying from tables I have no access rights to, so cannot create tables etc. I am looking to query and not declare and set values.
ID,
CASE
WHEN ORG1 = 1 THEN 'ORG1'
WHEN ORG2 = 1 THEN 'ORG2'
WHEN ORG3 = 1 THEN 'ORG3'
WHEN ORG4 = 1 THEN 'ORG4'
WHEN ORG5 = 1 THEN 'ORG5'
else 'None' end as ORG
FROM TBL
current table looks like:
ID ORG1 ORG2 ORG3 ORG4 ORG5
1 1 0 0 0 1
2 0 1 1 0 0
3 0 0 1 0 1
4 0 1 0 0 0
5 0 0 0 1 0
6 1 0 0 1 0
What I want it the outcome to look like is:
ID ORG
1 ORG1
1 ORG5
2 ORG2
2 ORG3
3 ORG3
3 ORG5
4 ORG2
5 ORG4
6 ORG1
6 ORG4
What I am getting with my code is:
ID ORG
1 ORG1
2 ORG2
3 ORG3
4 ORG2
5 ORG4
6 ORG1
Upvotes: 0
Views: 233
Reputation: 1269693
I would use cross apply
. However, you need additional logic for the 'NONE'
value -- even though your sample data doesn't include any examples:
SELECT t.ID, v.ORG
FROM TBL t CROSS APPLY
(VALUES ('ORG1', ORG1),
('ORG2', ORG2),
('ORG3', ORG3),
('ORG4', ORG4),
('ORG5', ORG5)
) V(ORG, val),
WHERE val = 1
UNION ALL
SELECT t.ID, 'None'
FROM TBL
WHERE ORG1 = 0 AND ORG2 = 0 AND ORG3 = 0 AND ORG4 = 0 AND ORG5 = 0;
Or without the UNION ALL
:
SELECT t.ID, v.ORG
FROM TBL t CROSS APPLY
(VALUES ('ORG1', ORG1),
('ORG2', ORG2),
('ORG3', ORG3),
('ORG4', ORG4),
('ORG5', ORG5),
('NONE', (CASE WHEN ORG1 = 0 AND ORG2 = 0 AND ORG3 = 0 AND ORG4 = 0 AND ORG5 = 0 THEN 1 ELSE 0 END))
) V(ORG, val),
WHERE val = 1
Upvotes: 0
Reputation: 13393
you can use this.
-- Sample Data
DECLARE @TBL TABLE (ID INT, ORG1 INT, ORG2 INT, ORG3 INT, ORG4 INT, ORG5 INT)
INSERT INTO @TBL VALUES
(1, 1, 0, 0, 0, 1),
(2, 0, 1, 1, 0, 0),
(3, 0, 0, 1, 0, 1),
(4, 0, 1, 0, 0, 0),
(5, 0, 0, 0, 1, 0),
(6, 1, 0, 0, 1, 0),
(7, 0, 0, 0, 0, 0)
SELECT ID, UNPVT.ORG FROM @TBL
UNPIVOT( VAL FOR ORG IN ([ORG1], [ORG2], [ORG3], [ORG4], [ORG5])) UNPVT
WHERE VAL = 1
Result:
ID ORG
----------- ------------
1 ORG1
1 ORG5
2 ORG2
2 ORG3
3 ORG3
3 ORG5
4 ORG2
5 ORG4
6 ORG1
6 ORG4
If you have cases which all columns are "0"
SELECT ID, UNPVT.ORG FROM
(SELECT *,
([ORG1] + [ORG2] + [ORG3] + [ORG4] + [ORG5])^1 AS [None]
FROM @TBL) SRC
UNPIVOT( VAL FOR ORG IN ([ORG1], [ORG2], [ORG3], [ORG4], [ORG5], [None])) UNPVT
WHERE VAL = 1
Result:
ID ORG
----------- ------------
1 ORG1
1 ORG5
2 ORG2
2 ORG3
3 ORG3
3 ORG5
4 ORG2
5 ORG4
6 ORG1
6 ORG4
7 None
Upvotes: 2
Reputation: 31993
do unpivot after using case expression
select id,org from (
select id, case when org1=1 then 'org1' end as og1,
case when org2=1 then 'org2' end as og2,
case when org3=1 then 'org3' end as og3,
case when org4=1 then 'org4' end as og4,
case when org5=1 then 'org5' end as og5
from table_name
) a unpivot (org for value in (og1,og2,og3,og4,og5)) p
id org
1 org1
1 org5
2 org2
2 org3
3 org3
3 org5
4 org2
5 org4
6 org1
6 org4
Upvotes: 0
Reputation: 4067
A simple approach would be a union all
like so:
select * from
(
select id, 'ORG1' as org from tbl where org1=1
union all
select id, 'ORG2' as org from tbl where org1=2
union all
select id, 'ORG3' as org from tbl where org1=3
union all
select id, 'ORG4' as org from tbl where org1=4
union all
select id, 'ORG5' as org from tbl where org1=5
) as tmp
I am guessing that you want to filter out all 0
columns. If not just delete the where clause
Upvotes: 0
Reputation: 8004
this is another approach
declare @Tbl as table (id int, org1 int, org2 int, org3 int, org4 int, org5 int)
insert into @Tbl values
(1,1,0,0,0,1),
(2,0,1,1,0,0),
(3,0,0,1,0,1),
(4,0,1,0,0,0),
(5,0,0,0,1,0),
(6,1,0,0,1,0)
select * from @Tbl
declare @temp as table (org varchar(5))
insert into @temp values
('org1'),('org2'),('org3'),('org4'),('org5')
select * from @temp
select * from @Tbl cross join @temp
where (org='org1' and org1=1) or
(org='org2' and org2=1) or
(org='org3' and org3=1) or
(org='org4' and org4=1) or
(org='org5' and org5=1)
order by id
Upvotes: 0