10

以下に簡単な表BIRDCOUNTがあり、特定の日に数えられた鳥の数を示しています。

+----------+
| NUMBIRDS |
+----------+
| 123      |
| 573      |
| 3        |
| 234      |
+----------+

鳥の数を数えた回数を示す度数分布グラフを作成したいと思います。したがって、次のようなものを作成するにはMySQLが必要です。

+------------+-------------+
| BIRD_COUNT | TIMES_SEEN  |
+------------+-------------+
| 0-99       | 17          |
| 100-299    | 23          |
| 200-399    | 12          |
| 300-499    | 122         |
| 400-599    | 3           |
+------------+-------------+

鳥の数の範囲が修正されていれば、これは簡単です。しかし、何羽の鳥が見られたかの最小値/最大値はわかりません。したがって、次のようなselectステートメントが必要です。

  1. 上記と同様の出力を作成し、常に10の範囲のカウントを作成します。
  2. (より高度な)上記と同様の出力を作成し、常にN範囲のカウントを作成します。

1回の選択で#2が可能かどうかはわかりませんが、誰でも#1を解決できますか?

4

4 に答える 4

8
SELECT
    FLOOR( birds.bird_count / stat.diff ) * stat.diff as range_start, 
    (FLOOR( birds.bird_count / stat.diff ) +1) * stat.diff -1 as range_end, 
    count( birds.bird_count ) as times_seen
FROM birds_table birds, 
    (SELECT 
        ROUND((MAX( bird_count ) - MIN( bird_count ))/10) AS diff
    FROM birds_table
    ) AS stat
GROUP BY FLOOR( birds.bird_count / stat.diff )

ここに両方の​​質問に対する答えがあります;]範囲の開始と終了が連結ではなく別々の列にあるという違いがありますが、1つの列で必要な場合は、ここから実行できると思います。範囲の数を変更するには、10番を編集するだけです。サブクエリで見つけることができます。

于 2013-02-24T21:52:52.783 に答える
3

このようなものを作成するとき、GROUPBYはあなたの友達です。基本的な考え方は、各値をバケットに入れてから、各バケットの要素の数を数えることです。バケットを作成するには、値を取得してバケットの一意の値を計算する関数を定義します。

このようなもの:

SELECT
  @low := TRUNCATE(bird_count/100, 0) * 100 as Low,
  TRUNCATE(@low + 99, 0) as High,
  COUNT(*) AS Count
FROM birds_seen
GROUP BY Low;

この場合、鳥の数を取得する関数を定義し、バケットのより低い範囲を計算します。次に、低い範囲のすべての値をグループ化します。これにより、たとえば、123と145が「100」というラベルの付いたバケットに配置され、234と246が「200」というラベルの付いたバケットに配置されます。

これで、各値がバケットに配置され、バケットラベルで値をグループ化し、各バケットの要素数をカウントできます。

于 2013-02-24T20:43:23.227 に答える
1

私はあなたの実際のSQLクエリを推測します:

SELECT dateColumn, COUNT(*) AS NUMBIRDS
FROM birdTable
GROUP BY dateColumn

もしそうなら、あなたがしなければならないのはあなたのカウントを「ビン」にすることです:

SELECT CONCAT_WS('-', 
   FLOOR( NUMBIRDS/100 )*100,
   ((FLOOR( NUMBIRDS/100 )+1)*100) - 1
) AS BIRD_COUNT
,COUNT(*) AS TIMES_SEEN
FROM (
    SELECT dateColumn, COUNT(*) AS NUMBIRDS
    FROM birdTable
    GROUP BY dateColumn
) AS birdCounts
GROUP BY BIRD_COUNT

確かに、範囲の1つが欠落している場合、一致する行は取得されませんが、それが問題である場合は、LEFTJOINを使用して簡単に解決できます。

于 2013-02-24T20:41:19.597 に答える
1

@gustekの回答とウィキペディアのヒストグラムページに基づいて、スコットのルールとライスのルールを使用して、ビンの数の式を使用してビンの幅hを動的に設定するいくつかのソリューションを次に示します。 k = \ ceil {(max --min)/ h}

# Histogram generator using Scott's rule, width(h) = (max - min) / k
SELECT any_value(FLOOR(r2.value / stat.width) * stat.width) as range_start,
       count(r2.value)                                      as times_seen,
FROM RESULT r2,
 (
     select 3.49 * stddev(r.value) / (power(count(*), 1 / 3)) as width
     from RESULT r
 ) as stat
GROUP BY FLOOR(r2.value / stat.width);

# Histogram using Rice rule k = ceil(2*n^1/3), width(h) = (max - min) / k
SELECT any_value(FLOOR(r2.value / stat.width) * stat.width) as range_start,
       count(r2.value)                                      as times_seen,
FROM RESULT r2,
 (
     select (max(r.value) - min(r.value)) / ceil(2 * power(count(*), 1 / 3)) as width
     from RESULT r
 ) as stat
GROUP BY FLOOR(r2.value / stat.width);

このany_value()関数は、MySQLの新しい問題を回避するために使用されますONLY_FULL_GROUP_BY

于 2019-06-21T03:37:15.520 に答える