히스토그램 그림에 대한 데이터 가져오기
MySQL에서 bin size를 지정하는 방법이 있나요?현재 다음 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)를 통해 numeric_value가 적절히 오프셋되지 않는 한 [0,4](5개 요소) 범위의 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 | * | +--------+----------+-----------------+
일부 참고: 일치하지 않는 범위는 카운트에 표시되지 않습니다. 카운트 열에 0이 표시되지 않습니다.또, 여기에서는 ROUND 기능을 사용하고 있습니다.더 타당하다고 생각되면 TRUNCATE로 쉽게 대체할 수 있습니다.
여기 http://blog.shlomoid.com/2011/08/how-to-quickly-create-histogram-in.html에서 찾았습니다.
Mike DelGaudio의 답변은 제 방식이지만, 약간의 변화가 있습니다.
select floor(mycol/10)*10 as bin_floor, count(*)
from mytable
group by 1
order by 1
빈을 원하는 만큼 크게 만들 수도 있고 작게 만들 수도 있습니다. 100? 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 열이 포함됩니다.오퍼레이터가 "displaced..."라는 점에 주의해 주십시오.on x between y와 z"는 포함입니다.
table1은 데이터 테이블의 이름입니다.
오프리 라비브count(*)
되다1
히스토그램 간격에 결과가 0인 경우에도 마찬가지입니다.해야 합니다.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 솔루션에서 사용할 수 있도록 지정된 개수나 크기에 따라 bin용 임시 테이블을 자동으로 생성하는 절차를 만들었습니다.
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
이렇게 하면 채워진 빈에 대해서만 히스토그램 카운트가 생성됩니다.David West의 수정 내용은 정확해야 하지만 어떤 이유에서인지 입력되지 않은 빈이 결과에 나타나지 않습니다(왼쪽 조인 사용에도 불구하고 왜 그런지 이해할 수 없습니다).
그러면 되겠군요.우아하지는 않지만, 고요함:
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 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;
주어진 빈 카운트에 동일한 폭의 빈 생성:
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)인 레코드가 자체 빈을 만들지 않도록 하기 위한 것입니다.또한 가법 상수는 열의 모든 값이 동일한 경우 쿼리가 0으로 나누어져 실패하지 않도록 하기 위한 것입니다.
또한 정수 나눗셈을 피하기 위해 빈의 카운트(이 예에서는 10)를 소수 마크로 써야 합니다(조정되지 않은 bin_width는 10진수일 수 있습니다).
좋은 답변 https://stackoverflow.com/a/10363145/916682, 외에 phpmyadmin 차트 도구를 사용하여 좋은 결과를 얻을 수 있습니다.
언급URL : https://stackoverflow.com/questions/1764881/getting-data-for-histogram-plot
'source' 카테고리의 다른 글
C 콘솔에 바이너리 트리를 그리는 방법 (0) | 2022.09.05 |
---|---|
ThreadPoolExecutor의 코어 풀 크기 대 최대 풀 크기 (0) | 2022.09.05 |
MySQL 8에서 동면 사투리를 사용하시겠습니까? (0) | 2022.09.05 |
데이터베이스 샤딩과 파티셔닝 (0) | 2022.09.05 |
다음 json 문자열을 java 개체로 변환하는 방법 (0) | 2022.09.05 |