Как заставить данные возвращать 0 при использовании UNION ALL? - PullRequest
0 голосов
/ 03 февраля 2020

При использовании UNION ALL данные не будут возвращать 0. Например, если частота для максимума в таблице равна нулю, она ничего не вернет. Вот почему я хочу применить внешнее объединение в моем коде

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        |

Вывод, который я получил для myid = 20

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

Желаемый вывод

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

Мой код:

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

Ответы [ 3 ]

2 голосов
/ 03 февраля 2020

Запрос UNION ALL недостаточен, поскольку он может содержать не все возможные значения score: 'high', 'low' и 'average'. Используйте запрос, который возвращает все эти возможные значения, и оставьте присоединение к запросу UNION ALL:

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

См. demo . Результаты:

> score   |  f
> :------ | -:
> average |  0
> high    |  1
> low     |  4
1 голос
/ 03 февраля 2020

Вы должны взять объединение двух таблиц, а затем агрегировать по ним:

SELECT
    myid,
    score,
    COUNT(*) AS f
FROM
(
    SELECT myid, score FROM table1
    UNION ALL
    SELECT myid, score FROM table2
) t
GROUP BY
    myid,
    score;
0 голосов
/ 03 февраля 2020

Вы можете использовать UNION обе таблицы, а затем GROUP BY myid. Например:

select
  myid, score, count(*) as f
from (
  select myid, score from table1
  union all
  select myid, score from table2
) x
group by myid, score

РЕДАКТИРОВАТЬ :

Если вы хотите всегда показывать значения high и low как ноль при отсутствии для них строк, Вы можете использовать LEFT JOIN, чтобы сделать это:

select myid, score, sum(c) as f
from (
  select 'low' as score union select 'high'
) s
left join (
  select myid, score, 1 as c from table1
  union all
  select myid, score, 1 from table2
) x on x.score = s.score
group by myid, score

Имейте в виду, я не проверял этот последний запрос.

...