下面我有一张简单的桌子,上面显示了每一天有多少只鸟被计算在内:
+----------+
| 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语句:
我不知道在一个选择中#2是否可行,但是谁能解决#1呢?
发布于 2013-02-24 21:52:52
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 )在这里,您对两个问题都有答案;]由于差异,范围的开始和结束是在单独的列中,而不是串联的,但是如果您需要在一列中,我想您可以从这里开始。要更改范围的数量,只需编辑数字10,您可以在子查询中找到。
发布于 2013-02-24 20:43:23
当你做这样的事情时,你的朋友就是你的朋友。其基本思想是将每个值放入桶中,然后计算每个桶中的元素数。要创建一个桶,您可以定义一个函数,该函数接受该值并计算桶的唯一值。
就像这样:
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-24 20:41:19
我猜您的实际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当然,如果其中一个区域丢失了,您将不会得到一个匹配的行--但是如果这是一个问题,您可以很容易地用左联接来解决这个问题。
https://stackoverflow.com/questions/15055540
复制相似问题