SQL查询,根据可变桶大小生成值的直方图

时间:2016-03-11 19:11:00

标签: sql sql-server-2012

我有一个如下所示的值表:

voltage
9.7329000
7.6746300
8.5768950
7.9966500
3.5873950
5.6055000
7.5666250
0.6287800

我正在寻找一个SQL查询来生成可能不同的桶大小的值的直方图。例如,如果桶大小为1.0,那么各种计数的桶是[0.0,1.0),[1.0,2.0),[2.0,3.0],[3.0,4.0],...在这种情况下,显示的数据的查询结果将是:

bucket    count
0.0       1
3.0       1
5.0       1
7.0       3
8.0       1
9.0       1

[编辑] 到目前为止,我有以下内容:

select floor([voltage]/1)*1 as bucket_flr, count(*) as count
from [db1].[dbo].[table]
group by floor([voltage]/1)*1
order by floor([voltage]/1)*1

这似乎有效,但我想知道是否有更优雅的东西。谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用递归CTE来获取结果集的限制:

CREATE TABLE dbo.Voltages (voltage DECIMAL(10, 7))

INSERT INTO dbo.Voltages (voltage)
VALUES
(9.7329000),
(7.6746300),
(8.5768950),
(7.9966500),
(3.5873950),
(5.6055000),
(7.5666250),
(0.6287800)

DECLARE @bucket_size DECIMAL(10, 7) = 1.0

;WITH
CTE_MaxVoltage AS (SELECT MAX(voltage) AS voltage FROM Voltages),
CTE_Buckets AS
(
    SELECT
        CAST(0.0 AS DECIMAL(10, 7)) AS bucket_start,
        CAST(0.0 + @bucket_size AS DECIMAL(10, 7)) AS bucket_end,
        1 AS bucket_number
    UNION ALL
    SELECT
        B.bucket_end,
        CAST(B.bucket_end + @bucket_size AS DECIMAL(10, 7)),
        B.bucket_number + 1
    FROM
        CTE_Buckets B
    INNER JOIN CTE_MaxVoltage MV ON MV.voltage > B.bucket_end
)
SELECT
    B.bucket_start AS bucket,
    COUNT(*) AS [count]
FROM
    CTE_Buckets B
INNER JOIN Voltages V ON
    voltage >= B.bucket_start AND
    voltage < B.bucket_end
GROUP BY
    B.bucket_start
ORDER BY
    B.bucket_start

DROP TABLE dbo.Voltages

我必须使用CAST来使递归CTE起作用。如果您想查看所有存储桶(即使是那些测量为0的存储桶),那么您可以将最后一个JOIN更改为LEFT OUTER JOIN并使用COUNT(V.voltage)而不是COUNT(*)