Gibt es eine Möglichkeit, Bin-Größen in MySQL anzugeben? Im Moment versuche ich die folgende SQL-Abfrage:
select total, count(total) from faults GROUP BY total;
Die Daten, die generiert werden, sind gut genug, aber es gibt einfach zu viele Zeilen. Was ich brauche, ist eine Möglichkeit, die Daten in vordefinierten Fächern zu gruppieren. Ich kann dies in einer Skriptsprache tun, aber gibt es eine Möglichkeit, dies direkt in SQL zu tun?
Beispiel:
+-------+--------------+
| 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 |
------------------------
Was ich suche:
+------------+---------------+
| total | count(total) |
+------------+---------------+
| 30 - 40 | 23 |
| 40 - 50 | 15 |
| 50 - 60 | 51 |
| 60 - 70 | 45 |
------------------------------
Ich denke, dies kann nicht auf einfache Weise erreicht werden, aber ein Verweis auf eine verwandte gespeicherte Prozedur wäre auch in Ordnung.
Antworten:
Ich fand es hier http://blog.shlomoid.com/2011/08/how-to-quickly-create-histogram-in.html
quelle
Die Antwort von Mike DelGaudio ist die Art und Weise, wie ich es mache, aber mit einer kleinen Änderung:
select floor(mycol/10)*10 as bin_floor, count(*) from mytable group by 1 order by 1
Der Vorteil? Sie können die Behälter so groß oder so klein machen, wie Sie möchten. Behälter der Größe 100?
floor(mycol/100)*100
. Behälter der Größe 5?floor(mycol/5)*5
.Bernardo.
quelle
concat(floor(mycol/5)*5," to ",floor(mycol/5)*5+5)
round(mycol, -2)
aus der akzeptierten Antwort tatsächlich besser als einfach , da der Benutzer jeden nicht dezimalen "Bereich" definieren kann. Ich würde nurround
anstelle von verwenden,floor
da es die Zahlen richtig rundet.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
Die Tabellenfächer enthalten die Spalten min_value und max_value, die die Fächer definieren. Beachten Sie, dass der Operator "join ... on x ZWISCHEN y und z" inklusive ist.
Tabelle1 ist der Name der Datentabelle
quelle
Die Antwort von Ofri Raviv ist sehr nah, aber falsch. Das
count(*)
wird sein ,1
selbst wenn es Null resultiert in einem Histogramm - Intervall. Die Abfrage muss geändert werden, um eine Bedingung zu verwendensum
: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;
quelle
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 ....
Solange es nicht zu viele Intervalle gibt, ist dies eine ziemlich gute Lösung.
quelle
Ich habe eine Prozedur erstellt, mit der automatisch eine temporäre Tabelle für Bins gemäß einer bestimmten Anzahl oder Größe generiert werden kann, die später mit der Lösung von Ofri Raviv verwendet werden kann.
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
Dadurch wird die Histogrammanzahl nur für die ausgefüllten Bins generiert. David West sollte in seiner Korrektur Recht haben, aber aus irgendeinem Grund erscheinen unbewohnte Behälter für mich nicht im Ergebnis (trotz der Verwendung eines LEFT JOIN - ich verstehe nicht warum).
quelle
Das sollte funktionieren. Nicht so elegant, aber trotzdem:
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
über Mike DelGaudio
quelle
SELECT CASE WHEN total <= 30 THEN "0-30" WHEN total <= 40 THEN "31-40" WHEN total <= 50 THEN "41-50" ELSE "50-" END as Total, count(*) as count GROUP BY Total ORDER BY Total;
quelle
Gleiches Binning in eine bestimmte Anzahl von Bins:
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;
Beachten Sie, dass 0,0000001 vorhanden ist, um sicherzustellen, dass die Datensätze mit dem Wert max (col) nicht allein einen eigenen Bin erstellen. Die additive Konstante soll außerdem sicherstellen, dass die Abfrage bei der Division durch Null nicht fehlschlägt, wenn alle Werte in der Spalte identisch sind.
Beachten Sie auch, dass die Anzahl der Bins (im Beispiel 10) mit einer Dezimalstelle geschrieben werden sollte, um eine Ganzzahldivision zu vermeiden (die nicht angepasste bin_width kann dezimal sein).
quelle
WITH something AS
ist sehr nützlich, wenn Sie den Wert berechnen müssen, der in die Fächer gelangt.Zusätzlich zu der großartigen Antwort https://stackoverflow.com/a/10363145/916682 können Sie das Diagramm-Tool phpmyadmin verwenden, um ein gutes Ergebnis zu erzielen:
quelle