SQL中的直方图,不跳过值

时间:2015-07-17 18:04:59

标签: sql

我有代码

select 
    floor(value / 5) * 5 as binned_value,
    count(*) as qty
from 
    myTable
group by
    binned_value;

实施例

输入

| id | value| 
|----|------|
| 1  | 0    |
| 2  | 4    |
| 3  | 3    |
| 4  | 12   |

输出

| binned_value | qty |
|--------------|-----|
| 0            | 3   |
| 10           | 1   |

这意味着0..5之间有3个值,10..15之间有1个值。

问题

我希望输出为:

| binned_value | qty |
|--------------|-----|
| 0            | 3   |
| 5            | 0   |
| 10           | 1   |

也就是说,我想要显示任何具有0数量的bin。

我知道我可以通过一堆连接和联合来做到这一点,但是5,bin大小,是一个参数。

可以预先知道最高可能值。

2 个答案:

答案 0 :(得分:1)

您可以使用递归CTE获得5的倍数(在下面的示例中,II得到15,但您可以将其增加到任何值)。然后使您的查询成为子查询并加入它。

WITH NumbersByFive AS
(
    SELECT n = 0
    UNION ALL
    SELECT n + 5 FROM NumbersByFive WHERE n <= 15 

)
SELECT nbf.n AS binned_value,
       ISNULL(qty,0) AS qty
FROM
NumbersByFive nbf
LEFT JOIN
(
    select 
        floor(value / 5) * 5 as binned_value
        ,count(*) as qty
    from myTable b
    group by floor(value / 5) * 5
) Subqry
ON nbf.n = Subqry.binned_Value

答案 1 :(得分:1)

在这里,我检查myTable中的最大值,以便首先创建bin列表

这是sqlFiddle DEMO

;WITH n(n) AS
(
    SELECT 0
    UNION ALL
    SELECT n + 5 
    FROM n 
    WHERE n + 5 < ( select m.Value 
                    from 
                    myTable m
                    where not exists (select Value 
                                      from mytable t 
                                      where m.Value < t.Value
                                     )
                  )
), 
CTE as 
(
  select 
      floor(value / 5) * 5 as binned_value,
      count(*) as qty
  from 
      myTable
  group by
      floor(value / 5) * 5
)
SELECT n AS binned_value,
       ISNULL(qty,0) AS qty
FROM 
    n  LEFT JOIN
    CTE on n.n = CTE.binned_value
OPTION (MAXRECURSION 1000);