Получение данных для графика гистограммы

Есть ли способ указать размеры бинов в 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 должно быть смещено в операции ROUNDING на основе увеличения округления, чтобы гарантировать, что первое ведро содержит столько элементов, сколько следующие ковши.

например, с ROUND (numeric_value, -1), числовое значение в диапазоне [0,4] (5 элементов) будет помещено в первое ведро, тогда как [5,14] (10 элементов) в секунду, [15,24] в третьем, если значение numeric_value не будет соответствующим образом смещено через ROUND (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

Ответ Майка Дель Гаудио – это то, как я это делаю, но с небольшими изменениями:

 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, которые определяют ячейки. обратите внимание, что оператор «join … on x BETWEEN y и z» включен.

table1 – это имя таблицы данных

Ответ Отри Равива очень близкий, но неправильный. 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((@[email protected])/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 

Это приведет к подсчету гистограммы только для заполненных бункеров. Дэвид Уэст должен быть прав в своем исправлении, но по какой-то причине для меня не появляются неопытные бункеры (несмотря на использование ЛЕВОЙ ВСТРЕЧИ - я не понимаю, почему).

Это должно сработать. Не так элегантно, но все же:

 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 

через Mike 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 должен удостовериться, что записи со значением, равным max (col), сами по себе не делают собственный бункер. Кроме того, существует константа аддитивности, чтобы убедиться, что запрос не прерывается при делении на ноль, когда все значения в столбце идентичны.

Также обратите внимание, что количество бункеров (10 в примере) должно быть записано с десятичной меткой, чтобы избежать целочисленного деления (unadjusted bin_width может быть десятичным).

  • Событие Cronjob или MySQL?
  • Ранг () над разделом в mysql
  • Excel VBA: запись в базу данных mysql
  • Почему оцененные ряды очень сильно отличаются по результатам phpmyadmin?
  • Показать ограничения для команды таблиц
  • MySQL: ALTER IGNORE TABLE дает «Нарушение ограничения целостности»
  • LOAD DATA INFILE легко конвертировать YYYYMMDD в ГГГГ-ММ-ДД?
  • импортирование CSV в phpmyadmin
  • Как правильно создавать составные первичные ключи - MYSQL
  • Находите диапазон диапазонов дат в пределах одной таблицы, для конкретного пользователя MySQL
  • Разделительная строка с разделителями разделов MySQL в таблицу Temp
  • Давайте будем гением компьютера.