Reputation: 39
I have table like this:
ID | PRODUCT |
---|---|
1 | APPLE |
2 | SUMSUNG |
2 | APPLE |
3 | HUAWEI |
4 | XIAMO |
4 | APPLE |
The product is devided into two types: ios and android. I want to get a table like this:
ID | IOS | ANDDROID |
---|---|---|
1 | YES | NO |
2 | YES | YES |
3 | NO | YES |
4 | YES | YES |
I tried :
select id,
case when product = 'APPLE' THEN 'YES' ELSE 'NO' END as 'IOS',
case when product in ('SUMSUNG', 'HUAWEI', 'XIAMO') THEN 'YES' ELSE 'NO' END AS 'ANDROID'
from table
But i got this table:
ID | IOS | ANDDROID |
---|---|---|
1 | YES | NO |
2 | YES | NO |
2 | NO | YES |
3 | NO | YES |
4 | YES | NO |
4 | NO | YES |
Upvotes: 0
Views: 65
Reputation: 65158
You can construct the logic depending on the brand APPLE
,as that's the unique member(APPLE
) for its own operating system (IOS
) such as
SELECT id,
DECODE(SIGN(SUM(DECODE(product,'APPLE',1,0))),1,'YES','NO') AS ios,
DECODE(SIGN(SUM(DECODE(product,'APPLE',0,1))),1,'YES','NO') AS android
FROM t
GROUP BY id
ORDER BY id
where the inner conditionals along with SUM()
aggregation by grouped by id
column and the signum function check the existence/unexistence of APPLE
by binary digits, and then replaces them with the words YES
/NO
Upvotes: 1
Reputation: 1332
You can aggregate to ensure that the id only shows up once:
select id,
MAX(case when product = 'APPLE' THEN 'YES' END) as 'IOS',
MAX(case when product in ('SUMSUNG', 'HUAWEI', 'XIAMO') THEN 'YES' END) AS 'ANDROID'
from table
GROUP BY id
That ensures you get one row per id - but you get NULL instead of 'NO'. To fix that use COALESCE.
select id,
COALESCE(MAX(case when product = 'APPLE' THEN 'YES' END),'NO') as 'IOS',
COALESCE(MAX(case when product in ('SUMSUNG', 'HUAWEI', 'XIAMO') THEN 'YES' END),'NO') AS 'ANDROID'
from table
GROUP BY id
Upvotes: 2
Reputation: 142720
You'll need yet another - mapping
- table which shows which operating system belongs to which product. Yes, you can hardcode it into the query, but that's generally a bad idea. You can't modify query every time new product appears on the market, can you? Sure you can, but you shouldn't.
SQL> with mapping (product, os) as
2 (select 'APPLE' , 'IOS' from dual union all
3 select 'SAMSUNG', 'ANDROID' from dual union all
4 select 'HUAWEI' , 'ANDROID' from dual union all
5 select 'XIAMO' , 'ANDROID' from dual
6 ),
7 your_table (id, product) as
8 (select 1, 'APPLE' from dual union all
9 select 2, 'SAMSUNG' from dual union all
10 select 2, 'APPLE' from dual union all
11 select 3, 'HUAWEI' from dual union all
12 select 4, 'XIAMO' from dual union all
13 select 4, 'APPLE' from dual
14 )
15 select y.id,
16 max(case when p.os = 'IOS' then 'YES' else 'NO' end) as ios,
17 max(case when p.os = 'ANDROID' then 'YES' else 'NO' end) as android
18 from your_table y join mapping p on p.product = y.product
19 group by y.id
20 order by y.id;
ID IOS AND
---------- --- ---
1 YES NO
2 YES YES
3 NO YES
4 YES YES
SQL>
Upvotes: 2