Sql 从数据库中的列值生成直方图

Sql 从数据库中的列值生成直方图,sql,sql-server,histogram,Sql,Sql Server,Histogram,假设我有一个数据库列“grade”,如下所示: |grade| | 1| | 2| | 1| | 3| | 4| | 5| SQL中有没有一种非常简单的方法可以生成这样的直方图 |2,1,1,1,1,0| 其中2表示等级1出现两次,1s表示等级{2..5}出现一次,0表示等级6根本不出现 我不介意柱状图是每计数一行 如果这很重要,那么数据库就是由perl CGI通过unixODBC/FreeTDS访问的SQL Server 编辑:谢谢你的快速回复!只要我能

假设我有一个数据库列“grade”,如下所示:

|grade|
|    1|
|    2|
|    1|
|    3|
|    4|
|    5|
SQL中有没有一种非常简单的方法可以生成这样的直方图

|2,1,1,1,1,0|
其中2表示等级1出现两次,1s表示等级{2..5}出现一次,0表示等级6根本不出现

我不介意柱状图是每计数一行

如果这很重要,那么数据库就是由perl CGI通过unixODBC/FreeTDS访问的SQL Server

编辑:谢谢你的快速回复!只要我能确定哪个直方图值属于哪个级别,就可以确定上面示例中不存在的值(如6级)不会出现

SELECT COUNT(grade) FROM table GROUP BY grade ORDER BY grade

还没有验证,但它应该可以工作。但是,它不会显示6s等级的计数,因为它根本不在表中…

Gamecat使用DISTINCT对我来说有点奇怪,我回到办公室后必须尝试一下

select Grade, count(Grade)
from MyTable
group by Grade
我会做的方式是相似的,虽然

SELECT
    [table].grade        AS [grade],
    COUNT(*)             AS [occurances]
FROM
    [table]
GROUP BY
    [table].grade
ORDER BY
    [table].grade
为了克服0次发生时数据不足的问题,您可以将JOIN保留在包含所有有效等级的表上。COUNT*将计算空值,但COUNTgrade不会计算空值

DECLARE @grades TABLE (
   val INT
   )  

INSERT INTO @grades VALUES (1)  
INSERT INTO @grades VALUES (2)  
INSERT INTO @grades VALUES (3)  
INSERT INTO @grades VALUES (4)  
INSERT INTO @grades VALUES (5)  
INSERT INTO @grades VALUES (6)  

SELECT
    [grades].val         AS [grade],
    COUNT([table].grade) AS [occurances]
FROM
    @grades   AS [grades]
LEFT JOIN
    [table]
        ON [table].grade = [grades].val
GROUP BY
    [grades].val
ORDER BY
    [grades].val

使用临时表获取缺少的值:

CREATE TABLE #tmp(num int)
DECLARE @num int
SET @num = 0
WHILE @num < 10
BEGIN
  INSERT #tmp @num
  SET @num = @num + 1
END


SELECT t.num as [Grade], count(g.Grade) FROM gradeTable g
RIGHT JOIN #tmp t on g.Grade = t.num
GROUP by t.num
ORDER BY 1

根据Shlomo Priymak的文章,您可以使用以下查询:

选择等级, 将*计数为“计数”, RPAD,计数*,“*”作为“条” 分级 分组 将生成下表:

等级计数条 1 2 ** 2 1 * 3 1 * 4 1 * 5 1 *
我以Ilya Volodin在上面所做的为基础,这应该允许你选择一系列你想在结果中分组的分数:

DECLARE @cnt INT = 0;

WHILE @cnt < 100 -- Set max value
BEGIN
SELECT @cnt,COUNT(fe) FROM dbo.GEODATA_CB where fe >= @cnt-0.999 and fe <= @cnt+0.999 -- set tolerance
SET @cnt = @cnt + 1; -- set step
END;

如果有很多数据点,您也可以这样:

|grade|
|    1|
|    2|
|    1|
|    3|
|    4|
|    5|
选择地面坡度/5.00*5作为坡度, 计数*为[成绩计数] 从表名 按楼层级别分组/5.00*5 按1订购 此外,如果您想标记全系列,您可以使用CTE提前获得地板和天花板

等级范围为 选择FLOORScore/5.00*5作为平地, 地板芯/5.00*5+4作为坡度天花板 从表名 选择地面, 混凝土地面,“至”,地面天花板作为坡度范围, 计数*为[成绩计数] 从等级范围 按楼层、混凝土楼层、“至”楼层天花板分组 按楼层订购 注意:在某些SQL引擎中,您可以按顺序列索引进行分组,但对于MS SQL,如果您希望在SELECT语句中使用它,则还需要按它进行分组,从而将范围复制到组表达式中


选项2:您可以使用获取包含值的逐行计数

是的,我错了。错过了小组赛。SQL到rusty错误。更好的方法是:通过从sysobjects、sys.all_column中选择top 10 identityint、1、1作为num到tmp来生成标识表。这对于连续值也很有价值,例如带小数点的值,如金额,或表示平均值列表的一组值。KyleMit,谢谢你清理我的答案,但是编辑引入了虚假的反斜杠,没有得到医生的认可。也许有些SQL工具链容忍或需要这种语法混乱?