Отсутствует строка в запросе SQL, где счетчик равен 0, сгруппированный по диапазону значений - PullRequest
0 голосов
/ 16 мая 2018

У меня проблема с пропущенными строками в моем запросе SQL. Я хочу отобразить количество вхождений, сгруппированных по значениям, и таблица должна отображать их, даже если они не имеют значений на интервале.

Вот что он показывает сейчас

|---------------------|------------------|
|      Category       |       Amount     |
|---------------------|------------------|
|        <= 0         |        34        |
|---------------------|------------------|
|       ]0 - 1]       |        18        |
|---------------------|------------------|
|         > 2         |        25        |
|---------------------|------------------|

А вот что мне нужно, чтобы показать

|---------------------|------------------|
|      Category       |       Amount     |
|---------------------|------------------|
|        <= 0         |        34        |
|---------------------|------------------|
|       ]0 - 1]       |        18        |
|---------------------|------------------|
|       ]1 - 2]       |        0         |
|---------------------|------------------|
|         > 2         |        25        |
|---------------------|------------------|

Пока мой код:

SELECT  t.range AS Category,
      Count( * )  AS [Amount],
      FROM (
           SELECT value,
                  CASE 
                     WHEN (value <= 0) THEN ' <= 0 ' 
                     WHEN (value > 0 AND value <= 1) THEN ' ]0 - 1]' 
                     WHEN (value > 1 AND value <= 2) THEN ' ]1 - 2]' 
                     WHEN (value > 2 ) THEN ' > 2 ' 
                  END AS range
            FROM Table
       )
       t
GROUP BY t.range;

Есть идеи, как это решить?

Спасибо, уже!

Ответы [ 4 ]

0 голосов
/ 16 мая 2018
    select
CASE
                     WHEN (startRange <= 0) THEN ' <= 0 '
                     WHEN (startRange > 0 AND startRange <= 1) THEN ' ]0 - 1]'
                     WHEN (startRange > 1 AND startRange <= 2) THEN ' ]1 - 2]'
                     WHEN (startRange > 2 ) THEN ' > 2 '
                  END AS 'range',

  count(m.val) TotalCount
from test m right outer join(
select -100 startRange,0 endrange union all
select 0 startRange, 1 endrange union all
select 1 startRange, 2 endrange union all
select 2 startRange, 3 endrange union all
select 3 startRange, 4 endrange
)r
on m.val >=startrange
  and m.val < endrange
group by r.startRange, r.endRange;

Создание таблицы температур для диапазона и правильного внешнего соединения может решить проблему.Пожалуйста, обратитесь https://stackoverflow.com/a/15276614/5196927

0 голосов
/ 16 мая 2018

Просто сделайте несколько запросов, затем объедините их все:

SELECT ' <= 0 ' AS category, count(*) as Amount FROM MyTable WHERE value <= 0
UNION ALL
SELECT ' ]0 - 1]' AS category, count(*) FROM MyTable WHERE value > 0 AND value <= 1
UNION ALL
SELECT ' ]1 - 2]' AS category, count(*) FROM MyTable WHERE value > 1 AND value <= 2
UNION ALL
SELECT ' > 2 ' AS category, count(*) FROM MyTable WHERE value > 1 AND value > 2 
0 голосов
/ 16 мая 2018

Вы всегда определяете категории, поэтому мне кажется, что это должно быть table:

категории (id, диапазон)

и insert ваши диапазоны в этом table. Когда вы закончите с этим, решение будет таким же простым, как select ing from categories left join с другими table, при условии, что value соответствует указанному вами range , Для тех групп, у которых нет значений, результат будет null для count, поэтому вам нужно будет использовать ifnull, чтобы убедиться, что оно равно 0, если в группе нет записи.

Я не очень хорошо разбираюсь в SqLite, но в других СУБД вы можете добавить varchar к запросу, здесь varchar будет оценкой range, который вы сохранили в каждой категории, но если это в SqLite это не опция, тогда вы можете написать stored function, который будет сравнивать, основываясь на возможных значениях range. Это также не должно быть очень сложным, но если вы можете каким-то образом оценить строку range, то она должна быть предпочтительной (но только если исключена возможность какой-либо инъекции в диапазоны, но это другая тема).

0 голосов
/ 16 мая 2018

Давайте поговорим о вариантах здесь.

1-й вариант: обрабатывать это в логике приложения?

Думаю, я бы предпочел это, но это, конечно, зависит от того, что вам нужно с ним делать.

2-й вариант: использовать столбцы вместо строк

SELECT 
    SUM(CASE WHEN (value <= 0) THEN 1 ELSE 0 END) ' <= 0 '
    , SUM(CASE WHEN (value > 0 AND value <= 1) THEN 1 ELSE 0 END) ' ]0 - 1]'
    , SUM(CASE WHEN (value > 1 AND value <= 2) THEN 1 ELSE 0 END) ' ]1 - 2]' 
    , SUM(CASE WHEN (value > 2 ) THEN 1 ELSE 0 END) ' > 2 '
FROM Table 

3-й вариант: параметры жесткого кода в отдельном подзапросе (тот, который вы изначально хотели)

SELECT pos.r, COUNT(1) Amount
FROM (
        SELECT ' <= 0 ' r 
        UNION SELECT ' ]0 - 1]' r 
        UNION SELECT ' ]1 - 2]' r 
        UNION SELECT ' > 2 ' r
    ) pos 
    LEFT OUTER JOIN (
       SELECT value,
              CASE 
                 WHEN (value <= 0) THEN ' <= 0 ' 
                 WHEN (value > 0 AND value <= 1) THEN ' ]0 - 1]' 
                 WHEN (value > 1 AND value <= 2) THEN ' ]1 - 2]' 
                 WHEN (value > 2 ) THEN ' > 2 ' 
              END AS range
        FROM Table
    ) actual ON pos.r = actual.range
GROUP BY pos.r
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...