web-dev-qa-db-ja.com

データベースの列値からヒストグラムを生成する

次のようなデータベース列「grade」があるとしましょう。

|grade|
|    1|
|    2|
|    1|
|    3|
|    4|
|    5|

このようなヒストグラムを生成するためのSQLの重要な方法はありますか?

|2,1,1,1,1,0|

ここで、2はグレード1が2回発生することを意味し、1はグレード{2..5}が1回発生することを意味し、0はグレード6がまったく発生しないことを意味します。

ヒストグラムがカウントごとに1行であるかどうかは気にしません。

それが重要な場合、データベースは、unixODBC/FreeTDSを介してPerlCGIによってアクセスされるSQLServerです。

編集:迅速な返信ありがとうございます!どのヒストグラム値がどのグレードに属しているかがわかる限り、存在しない値(上記の例のグレード6など)が発生しなくても問題ありません。

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

検証はしていませんが、動作するはずですが、テーブルにまったく存在しないため、6sグレードのカウントは表示されません...

31
Ilya Volodin

一時テーブルを使用して、不足している値を取得します。

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
7
cjk

データポイントが多い場合は、次のようにすることもできます グループ範囲をまとめて

SELECT FLOOR(grade/5.00)*5 As Grade, 
       COUNT(*) AS [Grade Count]
FROM TableName
GROUP BY FLOOR(Grade/5.00)*5
ORDER BY 1

さらに、全範囲にラベルを付けたい場合は、CTEを使用して事前に床と天井を取得できます。

With GradeRanges As (
  SELECT FLOOR(Score/5.00)*5     As GradeFloor, 
         FLOOR(Score/5.00)*5 + 4 As GradeCeiling
  FROM TableName
)
SELECT GradeFloor,
       CONCAT(GradeFloor, ' to ', GradeCeiling) AS GradeRange,
       COUNT(*) AS [Grade Count]
FROM GradeRanges
GROUP BY GradeFloor, CONCAT(GradeFloor, ' to ', GradeCeiling)
ORDER BY GradeFloor

:一部のSQLエンジンでは、GROUP BY序数列インデックスですが、MS SQLでは、SELECTステートメントで必要な場合は、それによってグループ化する必要があるため、範囲もグループ式にコピーします。

オプション2caseステートメントを使用して値を任意のビンに選択的にカウントしてからピボットを解除する を使用して行ごとに取得できます含まれる値の数

7
KyleMit

GamecatのDISTINCTの使用は私には少し奇妙に思えます、私がオフィスに戻ったときにそれを試してみる必要があります...

私がそれをする方法は似ていますが...

SELECT
    [table].grade        AS [grade],
    COUNT(*)             AS [occurances]
FROM
    [table]
GROUP BY
    [table].grade
ORDER BY
    [table].grade

オカレンスが0のデータの不足を克服するために、すべての有効なグレードを含むテーブルに左結合することができます。 COUNT(*)はNULLをカウントしますが、COUNT(grade)はNULLをカウントしません。

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
3
MatBailie
select Grade, count(Grade)
from MyTable
group by Grade
2
Seibar

Shlomo Priymakの記事 MySQLでヒストグラムをすばやく作成する方法 によると、次のクエリを使用できます。

SELECT grade, 
       COUNT(\*) AS 'Count',
       RPAD('', COUNT(\*), '*') AS 'Bar' 
FROM grades 
GROUP BY grade

これにより、次のテーブルが生成されます。

grade   Count   Bar
1       2       **
2       1       *
3       1       *
4       1       *
5       1       *
2
devon

私はIlyaVolodinが上で行ったことに基づいて構築しています。これにより、結果でグループ化するグレードの範囲を選択できるようになります。

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;
0
Sylvain Ayrault