SQL请求中缺少按值范围分组的计数为0的行

SQL请求中缺少按值范围分组的计数为0的行,sql,database,sqlite,Sql,Database,Sqlite,我对SQL请求中缺少的一些行没有问题。我希望显示按值分组的引用数量,并且表格需要显示它们,即使它们在间隔上没有值 下面是它现在显示的内容 |---------------------|------------------| | Category | Amount | |---------------------|------------------| | <= 0 | 34 | |-----

我对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;
有没有办法解决这个问题


已经谢谢你了

让我们在这里讨论选项

第一个选项:在应用程序逻辑中处理它

我想我更喜欢这个,但这当然取决于你需要用它做什么

第二个选项:使用列而不是行

第三个选项:在单独的子查询中硬编码您最初想要的选项

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

只需执行多个查询,然后将它们全部合并:

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 

您总是在定义类别,因此我觉得它应该是一个表:

分类ID,范围

并在此表中插入您的范围。完成此操作后,解决方案将非常简单,只要在值满足指定范围的条件下,从类别中选择左键并与另一个表连接即可。对于那些没有值的组,计数的结果将为null,因此如果组中没有记录,则需要使用ifnull确保其为0

我不太熟悉SqLite,但在其他RDBMS中,您可以在查询中添加一个varchar,这里varchar将是对存储在每个类别中的范围的评估,但是如果SqLite中没有这个选项,那么您可以编写一个存储函数,它将根据可能的范围值进行比较。这应该也不是很难,但是如果您能够以某种方式内联计算范围字符串,那么应该首选它,但前提是排除了对范围进行任何注入的可能性,但这是一个不同的主题

    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;
为范围和右外部联接创建临时表可以解决此问题。
请参阅

虽然不是最有效的解决方案,但这可能是此用例最简单的解决方案。
    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;