2013-02-24 45 views
5

下面我有一個簡單的表BIRDCOUNT,顯示有多少鳥類計數在任何一天:mysql的創建工頻突變分佈

+----------+ 
| 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語句:

  1. 創建一個類似於上面的輸出,總是創建10個計數範圍。
  2. (更高級)創建類似於上面的輸出,始終創建N個計數範圍。

我不知道#2是否可能在一個選擇,但任何人都可以解決#1?

+0

到目前爲止,我在一次選擇中找到了最小值和最大值,然後分成了N個範圍,在PHP中構建了一個SELECT語句,以編程方式創建範圍,然後運行第二個選擇。這並不能真正幫助任何人提出答案,但是因爲你問了。 – TSG 2013-02-24 19:28:36

+0

你能給出同樣的樣本數據和你想要的結果嗎? – 2013-02-24 19:29:34

+0

,如果bird_count = 200,它會是哪一行? – 2013-02-24 19:31:28

回答

6
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您可以在子查詢中找到。

+0

這看起來很有前途(尚未測試)。我假設GROUP將強制每個範圍的總數(如WHERE> = range_start和<= range_end)...... – TSG 2013-02-25 02:42:03

+0

如果沒有鳥在任何單個範圍內計數,會發生什麼?我假設它不會創建一行輸出(即沒有鳥數爲0的行)。 – TSG 2013-02-25 16:26:41

+0

它不會。考慮一下你可以嘗試使用外連接,我會在幾分鐘內用例子編輯答案。如果您需要動態數量的範圍,則僅使用sql將會很困難。 – Gustek 2013-02-25 19:15:09

0

我想在您的實際的SQL查詢:

SELECT dateColumn, COUNT(*) AS NUMBIRDS 
FROM birdTable 
GROUP BY dateColumn 

如果是這樣,你需要做的是 「bin」 的您計數:

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 

當然,如果範圍之一缺少,你將不會得到一個匹配的行 - 但如果這是一個問題,你可以輕鬆解決這個問題。

0

創建類似這樣的內容時,GROUP BY是您的朋友。基本思想是將每個值放入一個桶中,然後計算每個桶中元素的數量。要創建一個存儲分區,您需要定義一個函數,該存儲分區獲取該值並計算該存儲分區的唯一值。

事情是這樣的:

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」的桶中。

現在,每個值都放在一個存儲桶中,您可以按照存儲桶標籤對這些值進行分組,並計算每個存儲桶中的元素數量。

+0

您不知道鳥的最高和最低數量,因此您的解決方案將創建大量範圍(每個大小均爲100)。 – TSG 2013-02-25 02:36:49

+0

並非如此,它只會爲實際在表中的值創建存儲區。 – 2013-02-26 10:10:02