質問
MySQLの中でビン・サイズを指定する方法はありますか?今、私は次のSQLクエリをしようとしています:
select total, count(total) from faults GROUP BY total;
生成されているデータが十分に良いのですが、あまりにも多くの行があります。私に必要なのは事前に定義されたビンにデータをグループ化する方法です。私は、スクリプト言語からこれを行うことができますが、SQLで直接それを行う方法はありますか?
例:
+-------+--------------+
| total | count(total) |
+-------+--------------+
| 30 | 1 |
| 31 | 2 |
| 33 | 1 |
| 34 | 3 |
| 35 | 2 |
| 36 | 6 |
| 37 | 3 |
| 38 | 2 |
| 41 | 1 |
| 42 | 5 |
| 43 | 1 |
| 44 | 7 |
| 45 | 4 |
| 46 | 3 |
| 47 | 2 |
| 49 | 3 |
| 50 | 2 |
| 51 | 3 |
| 52 | 4 |
| 53 | 2 |
| 54 | 1 |
| 55 | 3 |
| 56 | 4 |
| 57 | 4 |
| 58 | 2 |
| 59 | 2 |
| 60 | 4 |
| 61 | 1 |
| 63 | 2 |
| 64 | 5 |
| 65 | 2 |
| 66 | 3 |
| 67 | 5 |
| 68 | 5 |
------------------------
私が探しています何ます:
+------------+---------------+
| total | count(total) |
+------------+---------------+
| 30 - 40 | 23 |
| 40 - 50 | 15 |
| 50 - 60 | 51 |
| 60 - 70 | 45 |
------------------------------
私は、これは単純な方法で達成することができないが、任意の関連するストアドプロシージャへの参照は、同様に、微細であろうと思います。
解決
このヒストグラムを作成するために、スーパー間に合わせとウェイについての投稿です 数値のMySQLでます。
優れているヒストグラムを作成するには、他の複数の方法がありますし、 CASE文と複雑なロジックの他のタイプを使用して、より柔軟な。 それはとても簡単だけなので、この方法では、再び時間と時間をかけて私に勝利します 各ユースケースのために変更し、そう短く簡潔にします。どのようにこれは、 それを実行します。
SELECT ROUND(numeric_value, -2) AS bucket, COUNT(*) AS COUNT, RPAD('', LN(COUNT(*)), '*') AS bar FROM my_table GROUP BY bucket;
何でもあなたの列にだけ変更numeric_valueがあり、変更 増分を丸め、それはそれです。私はになるようにバーを作りました あなたが持っているとき、彼らはあまり成長しないので、対数スケール、 値が大きいます。
numeric_valueは最初のバケットは、次のバケットのような多くの要素として含まれて確保するために、丸めの増分に基づいて、丸め操作でオフセットされなければなりません。
例えば。一方、[5,14](10個の要素)ROUND(numeric_value、-1)を用いて、範囲内numeric_value [0,4](5要素)がない限り、[15,24]第三に、第二に、最初のバケットに配置されますnumeric_value丸を介して適切にオフセットされている(numeric_value - 5、-1)。
これがきれいに見えるいくつかのランダムなデータで、このようなクエリの例です。 甘い。データの迅速な評価のための良い十分ます。
+--------+----------+-----------------+ | bucket | count | bar | +--------+----------+-----------------+ | -500 | 1 | | | -400 | 2 | * | | -300 | 2 | * | | -200 | 9 | ** | | -100 | 52 | **** | | 0 | 5310766 | *************** | | 100 | 20779 | ********** | | 200 | 1865 | ******** | | 300 | 527 | ****** | | 400 | 170 | ***** | | 500 | 79 | **** | | 600 | 63 | **** | | 700 | 35 | **** | | 800 | 14 | *** | | 900 | 15 | *** | | 1000 | 6 | ** | | 1100 | 7 | ** | | 1200 | 8 | ** | | 1300 | 5 | ** | | 1400 | 2 | * | | 1500 | 4 | * | +--------+----------+-----------------+
いくつかの注意:一致を持っていない範囲は、カウントに表示されません - あなたは、カウント列にゼロを持っていません。また、私が使用しています ここROUND関数。あなたは同じように簡単にTRUNCATEでそれを置き換えることができます あなたが感じる場合、それはあなたに、より理にかなっています。
私はここでそれを見つけた http://blog.shlomoid.com /2011/08/how-to-quickly-create-histogram-in.htmlする
他のヒント
マイクDelGaudioの答えは、私はそれを行う方法ですが、若干の変更を伴うます:
select floor(mycol/10)*10 as bin_floor, count(*)
from mytable
group by 1
order by 1
利点?あなたが望むような大きな通りや小さなビンなどを作ることができます。サイズ100のビン? floor(mycol/100)*100
。サイズ5のビン? floor(mycol/5)*5
ます。
ベルナルドます。
SELECT b.*,count(*) as total FROM bins b
left outer join table1 a on a.value between b.min_value and b.max_value
group by b.min_value
はテーブルビンは、ビンを定義する列MIN_VALUEとMAX_VALUEを含有します。 オペレータは、「y、zの間のxに...参加する」というメモが含まれており。
table1のデータテーブルの名前です。
Ofri Ravivの答えは非常に近いが間違っています。 count(*)
は、ヒストグラムの区間でゼロの結果がある場合でも1
になります。
sum
を使用するように変更するためのクエリのニーズ
SELECT b.*, SUM(a.value IS NOT NULL) AS total FROM bins b
LEFT JOIN a ON a.value BETWEEN b.min_value AND b.max_value
GROUP BY b.min_value;
select "30-34" as TotalRange,count(total) as Count from table_name
where total between 30 and 34
union (
select "35-39" as TotalRange,count(total) as Count from table_name
where total between 35 and 39)
union (
select "40-44" as TotalRange,count(total) as Count from table_name
where total between 40 and 44)
union (
select "45-49" as TotalRange,count(total) as Count from table_name
where total between 45 and 49)
etc ....
限り、あまりにも多くの間隔がないとして、これはかなり良いソリューションです。
は私がOfri Ravivの溶液を用いて、後で使用するために、自動的に指定された数またはサイズに従ってビンのための一時的なテーブルを生成するために使用することができる手順を行った。
CREATE PROCEDURE makebins(numbins INT, binsize FLOAT) # binsize may be NULL for auto-size
BEGIN
SELECT FLOOR(MIN(colval)) INTO @binmin FROM yourtable;
SELECT CEIL(MAX(colval)) INTO @binmax FROM yourtable;
IF binsize IS NULL
THEN SET binsize = CEIL((@binmax-@binmin)/numbins); # CEIL here may prevent the potential creation a very small extra bin due to rounding errors, but no good where floats are needed.
END IF;
SET @currlim = @binmin;
WHILE @currlim + binsize < @binmax DO
INSERT INTO bins VALUES (@currlim, @currlim+binsize);
SET @currlim = @currlim + binsize;
END WHILE;
INSERT INTO bins VALUES (@currlim, @maxbin);
END;
DROP TABLE IF EXISTS bins; # be careful if you have a bins table of your own.
CREATE TEMPORARY TABLE bins (
minval INT, maxval INT, # or FLOAT, if needed
KEY (minval), KEY (maxval) );# keys could perhaps help if using a lot of bins; normally negligible
CALL makebins(20, NULL); # Using 20 bins of automatic size here.
SELECT bins.*, count(*) AS total FROM bins
LEFT JOIN yourtable ON yourtable.value BETWEEN bins.minval AND bins.maxval
GROUP BY bins.minval
これはのみ移入されたビンのヒストグラム・カウントを生成します。デビッド・ウェスト、右の彼の補正であるべき、いくつかの理由で、未実装のビンが私のために、結果には表示されません(LEFTの使用にもかかわらず、JOIN - 私はなぜ理解していない)。
これは動作するはずです。そのエレガントなまだありません。
select count(mycol - (mycol mod 10)) as freq, mycol - (mycol mod 10) as label
from mytable
group by mycol - (mycol mod 10)
order by mycol - (mycol mod 10) ASC
を経由してマイクDelGaudioする
select case when total >= 30 and total <= 40 THEN "30-40"
else when total >= 40 and total <= 50 then "40-50"
else "50-60" END as Total , count(total)
group by Total
偉大な答え https://stackoverflow.com/a/10363145/916682 のに加えて、あなたはphpmyadminのを使用することができます素敵な結果のためのチャートツールます:
等幅ビニングます:
WITH bins AS(
SELECT min(col) AS min_value
, ((max(col)-min(col)) / 10.0) + 0.0000001 AS bin_width
FROM cars
)
SELECT tab.*,
floor((col-bins.min_value) / bins.bin_width ) AS bin
FROM tab, bins;
0.0000001は必ず値を持つレコードが最大(COL)に等しいことを確認することがあること注ちょうど自分自身でそれ自身のビンをすることはありません。また、添加剤の定数は、列のすべての値が同一であるとき、必ずクエリは、ゼロによる除算に失敗しない作ることがあります。
ビンの数(この例では10)(未調整bin_widthは小数であってもよい)分割整数避けるため小数マークが書き込まれるべきであること。また、ノート