Search code examples
mysqljoincountfrequency

How to make the data return 0 when using UNION ALL?


When using UNION ALL,the data will not return 0. For example, if the frequency for high in table score is zero, it will return nothing. That is why I want to apply outer join in my code

Table1

  id    |   myid     |    score       |
---------------------------------------
1       |    20      |    high        |
2       |    20      |    low         |
3       |    21      |    average        |
4       |    21      |    high        |
5       |    21      |    low         |

Table2

 id2    |   myid     |   score      |
-------------------------------------
1       |    21      |   high       |
2       |    21      |   low        |
3       |    20      |   low        |
4       |    20      |   low        |
5       |    20      |   low        |

The output that I got for myid=20

myid     |  score       | f  |
-------------------------------
 20      |   low        | 4   |
 20      |   high       | 1   |  

Desired output

 myid    |  score       | f  |
-------------------------------
 20      |   low        | 4   |
 20      |   high       | 1   |  
 20      |   average    | 0   | 

My code:

select myid, score, count(*) as f
from
(
  select myid, score from table1 where myid=12
  union all
  select myid, score from table2 where myid=12
) unioned
group by myid, score

Solution

  • The UNION ALL query is not enough because it may not contain all the possible values of score: 'high', 'low' and 'average'.
    Use a query that returns all these possible values and left join the UNION ALL query:

    select s.score, count(t.score) f
    from (select 'high' score union all select 'low' union all select 'average') s
    left join (
      select * from Table1 where myid = 20
      union all
      select * from Table2 where myid = 20
    ) t on t.score = s.score
    group by s.score
    

    See the demo.
    Results:

    > score   |  f
    > :------ | -:
    > average |  0
    > high    |  1
    > low     |  4