我有一個MySQL數據庫,其中一列包含狀態碼。該列的類型爲int,值將只有100,200,300,400。它看起來像下面;爲清楚起見,刪除了其他列從以前的N行MySQL數據庫中獲取運行頻率分佈
id | status
----------------
1 300
2 100
3 100
4 200
5 300
6 300
7 100
8 400
9 200
10 300
11 100
12 400
13 400
14 400
15 300
16 300
id字段是自動生成的,並且始終是連續的。我想要第三列顯示前10行狀態代碼頻率分佈的逗號分隔字符串。它應該看起來像這樣。
id | status | freq
-----------------------------------
1 300
2 100
3 100
4 200
5 200
6 300
7 100
8 400
9 300
10 300
11 100 300,100,200,400 -- from rows 1-10
12 400 100,300,200,400 -- from rows 2-11
13 400 100,300,200,400 -- from rows 3-12
14 400 300,400,100,200 -- from rows 4-13
15 300 400,300,100,200 -- from rows 5-14
16 300 300,400,100 -- from rows 6-15
我想要列出最頻繁的代碼。在兩個狀態碼具有相同頻率的情況下,首先列出的並不重要,但是我在示例中的較大範圍之前列出了較小的代碼。最後,在前10行中代碼完全不出現的地方,它也不應該列在頻率列中。
並且要非常清楚頻率字符串出現的行號確實是不是考慮到該行的狀態碼;它只是以前的行。
那麼我做了什麼?我用SQL很綠。我是一名程序員,我發現這種SQL語言有點古怪。我管理了以下自加入選擇語句。
select *, avg(b.status) freq
from sample a
join sample b
on (b.id < a.id) and (b.id > a.id - 11)
where a.id > 10
group by a.id;
使用集合函數avg,我至少可以證明這個概念。派生表b爲avg函數提供了正確的行,但我無法弄清楚從b計算和分組行以獲取頻率分佈,然後將頻率行摺疊爲單個字符串值的多步過程。
另外我已經嘗試使用標準存儲的函數和過程來代替內置的聚合函數,但它似乎是b派生表超出了範圍或東西。我似乎無法訪問它。從我的理解來說,編寫一個自定義的聚合函數對我來說是不可能的,因爲它似乎需要用C開發,這是我沒有受過培訓的。
以下是加載示例的sql。
create table sample (
id int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
status int
);
insert into sample(status) values(300),(100),(100),(200),(200),(300)
,(100),(400),(300),(300),(100),(400),(400),(400),(300),(300),(300)
,(100),(400),(100),(100),(200),(500),(300),(100),(400),(200),(100)
,(500),(300);
該示例有30行數據要使用。我知道這是一個很長的問題,但我只想盡可能詳細。我已經爲此工作了幾天,並且很想完成它。
感謝您的幫助。
只是一個側面說明:'b.id> a.id - 如果你從來沒有刪除行並沒有插入過失敗11'纔會工作。否則,你不能依靠ID值 – 2011-04-21 08:08:11
沒有差距的事實。這是正確的。但是,在這個特定的應用程序中,我可以保證id字段始終是連續的。謝謝。 – Nick 2011-04-21 21:29:13