Reputation: 5
I have the following data:
And I want to know how often each value exists in each column. So my preferred output should look like this:
I'd be really grateful, if anybody can help me. Thanks!
Upvotes: 0
Views: 81
Reputation: 167822
Use UNPIVOT
then PIVOT
:
Oracle 11g R2 Schema Setup:
CREATE TABLE table_name ( a, b, c, d ) AS
SELECT 1, 2, 1, 2 FROM DUAL UNION ALL
SELECT 1, 2, 2, 2 FROM DUAL UNION ALL
SELECT 2, 1, 3, 3 FROM DUAL UNION ALL
SELECT 3, 3, 2, 4 FROM DUAL UNION ALL
SELECT 4, 4, 2, 5 FROM DUAL UNION ALL
SELECT 5, 5, 5, 5 FROM DUAL;
Query 1:
SELECT *
FROM table_name
UNPIVOT( value FOR name IN ( A, B, C, D ) )
PIVOT ( COUNT(1) FOR name IN ( 'A' AS A, 'B' AS B, 'C' AS C, 'D' AS D ) )
| VALUE | A | B | C | D |
|-------|---|---|---|---|
| 1 | 2 | 1 | 1 | 0 |
| 2 | 1 | 2 | 3 | 2 |
| 4 | 1 | 1 | 0 | 1 |
| 5 | 1 | 1 | 1 | 2 |
| 3 | 1 | 1 | 1 | 1 |
Upvotes: 0
Reputation:
with
inputs ( a, b, c, d ) as (
select 1, 2, 1, 2 from dual union all
select 1, 2, 2, 2 from dual union all
select 2, 1, 3, 3 from dual union all
select 3, 3, 2, 4 from dual union all
select 4, 4, 2, 5 from dual union all
select 5, 5, 5, 5 from dual
)
-- End of simulated inputs (for testing only, not part of the solution).
-- SQL query begins BELOW THIS LINE. Use your actual table and column names.
select grade,
count(case when a = grade then 0 end) as a,
count(case when b = grade then 0 end) as b,
count(case when c = grade then 0 end) as c,
count(case when d = grade then 0 end) as d
from inputs cross join (select level as grade from dual connect by level <= 5)
group by grade
order by grade
;
GRADE A B C D
---------- ---------- ---------- ---------- ----------
1 2 1 1 0
2 1 2 3 2
3 1 1 1 1
4 1 1 0 1
5 1 1 1 2
NOTE: This is essentially the same as MT0's solution, but both the unpivoting and the pivoting are done the "old way" (as they were done before PIVOT and UNPIVOT operators were introduced in Oracle 11.1).
Upvotes: 1
Reputation: 94859
That's a weird table structure and/or task. You may want to think over your database design. Anyway ...
select
num,
coalesce(agga.cnt, 0) as a,
coalesce(aggb.cnt, 0) as b,
coalesce(aggc.cnt, 0) as c,
coalesce(aggd.cnt, 0) as d
from (select a as num, count(*) as cnt from mytable group by a) agga
full outer join (select b as num, count(*) as cnt from mytable group by b) aggb using(num)
full outer join (select c as num, count(*) as cnt from mytable group by c) aggc using(num)
full outer join (select d as num, count(*) as cnt from mytable group by d) aggd using(num)
order by num;
Upvotes: 0